[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

Directories, string formatting, and security


A few fine points before we move on. First of all, make sure the web server script we
wrote earlier in Example 1-32 is running before you proceed; it’s going to catch our
requests and route them to our script.


Also notice how this script adds the current working directory (os.getcwd) to the
sys.path module search path when it first starts. Barring a PYTHONPATH change, this is
required to allow both the pickler and this script itself to import the person module one
level up from the script. Because of the new way the web server runs CGI scripts in
Python 3, the current working directory isn’t added to sys.path, even though the
shelve’s files are located there correctly when opened. Such details can vary per server.


The only other feat of semi-magic the CGI script relies on is using a record’s attribute
dictionary (dict) as the source of values when applying HTML escapes to field
values and string formatting to the HTML reply template string in the last line of the
script. Recall that a %(key)code replacement target fetches a value by key from a
dictionary:


>>> D = {'say': 5, 'get': 'shrubbery'}
>>> D['say']
5
>>> S = '%(say)s => %(get)s' % D
>>> S
'5 => shrubbery'

By using an object’s attribute dictionary, we can refer to attributes by name in the format
string. In fact, part of the reply template is generated by code. If its structure is con-
fusing, simply insert statements to print replyhtml and to call sys.exit, and run from
a simple command line. This is how the table’s HTML in the middle of the reply is
generated (slightly formatted here for readability):


<table>
<tr><th>key<td><input type=text name=key value="%(key)s">
<tr><th>name<td><input type=text name=name value="%(name)s">
<tr><th>age<td><input type=text name=age value="%(age)s">
<tr><th>job<td><input type=text name=job value="%(job)s">
<tr><th>pay<td><input type=text name=pay value="%(pay)s">
</table>

This text is then filled in with key values from the record’s attribute dictionary by string
formatting at the end of the script. This is done after running the dictionary through a
utility to convert its values to code text with repr and escape that text per HTML
conventions with cgi.escape (again, the last step isn’t always required, but it’s generally
a good practice).


These HTML reply lines could have been hardcoded in the script, but generating them
from a tuple of field names is a more general approach—we can add new fields in the
future without having to update the HTML template each time. Python’s string pro-
cessing tools make this a snap.


Step 6: Adding a Web Interface | 63
Free download pdf