[Tutor] Here's something to talk about
RWeidner at ea.com
Thu Apr 16 00:56:08 CEST 2009
1. Python is not Java (see Philip Eby's blog entry
http://dirtsimple.org/2004/12/python-is-not-java.html). Let go of your
concepts that only Items can go into an ItemCollection - Python already has
some perfectly good collection builtins. Instead of writing a custom
ItemCollection, why not write a generic Exporter that takes any Python
sequence (such as a list, set, tuple, etc., anything that supports iter)?
2. SQLExporter does not use recommended form for substituting values into an
SQL statement. It is preferred that one use the 2-argument form of execute,
in which the first argument contains '?' or '%s' placeholders, and the
second argument is a tuple of values. That is, instead of:
first, last = "Bobby", "Tables"
cursor.execute("INSERT into STUDENT (firstname, lastname) values
first, last = "Bobby", "Tables"
cursor.execute("INSERT into STUDENT (firstname, lastname) values (?,?)",
No need for wrapping in quotes, already handles values with embedded quotes,
and no SQL injection jeopardy (http://xkcd.com/327/). This slightly
complicates your SQL exporter, it would have to return a tuple containing
the INSERT statement and the tuple of substitution values, instead of just a
string to be passed to execute.
3. The Pythonic way to create a comma-separated string of values from a list
of strings is: ','.join(value_list). If you have a list of tuples and want
two comma-separated strings, do: keystring, valstring = (','.join(s) for s
4. While I am not a slave to PEP8, your mixed case method names with leading
capitals look too much like class names and/or .Net method names.
In general, I find your approach too intrusive into the objects you would
like to export or load. I would prefer to see a Loader and/or Exporter
class that takes my own application object, configured with table name and
field names, and then creates the proper XML or SQL representation.
In the future, I'll try not to have a Java accent when speaking Python.
( No guarantee though :) ) That said, thanks for the syntax tips and
Python preferred snips.
One of your points represents a great opportunity to make mine. Suppose
this code is several years old. Now we have a new requirement that
states we need to work with the data as you described above. How
much of the existing code would you have to change to make that change
happen? The answer is exactly one line. And here is the line...
exporter = SQLExporter("itemTable")
And you would change the line to something like...
exporter = SQLTupleExporter("itemTable")
exporter = ExportItemToDatabase('127.0.0.1', 'user', 'pass', 'schema')
Of course, you would need to define a class to go along with your change
but all of that will be NEW code. Not a change to existing code. So,
all of your existing code should still be valid and tested. The only
thing you'll need to do validate and test your new code.
There are no tentacles. Replacing exporter with a different kind of
exporter does not invalidate anything you've done in your code before.
Maybe you need to do both? Maybe you need to export the old way, and
export the new way. How difficult would that be with 2 export
objects? In this case, you wouldn't need to change any lines of code,
but rather you would add 2 more lines to the main logic and
implement the needed class.
It's really just a strategy for creating maintainable code. Maybe
It's a good strategy, maybe it isn't. I guess it would depend on
the project. I find the technique interesting and useful.
More information about the Tutor