Python Coding Style
Python Coding Style
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 2 of 32
—Tim Peters
This particular "poem" began as a kind of a joke, but it really embeds a lot of truth about the
philosophy behind Python. The Zen of Python has been formalized in PEP 20, where the abstract
reads:
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 3 of 32
Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding principles for
Python's design into 20 aphorisms, only 19 of which have been written down.
—http://www.python.org/dev/peps/pep-
0020/
You can decide for yourself if you're a "Pythoneer" or a "Pythonista". The terms have somewhat
different connotations.
When in doubt:
import this
http://www.python.org/dev/peps/pep-0008/
A PEP is a design document providing information to the Python community, or describing a new
feature for Python or its processes or environment.
The Python community has its own standards for what source code should look like, codified in PEP
8. These standards are different from those of other communities, like C, C++, C#, Java, VisualBasic,
etc.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 4 of 32
Because indentation and whitespace are so important in Python, the Style Guide for Python Code
approaches a standard. It would be wise to adhere to the guide! Most open-source projects and
(hopefully) in-house projects follow the style guide quite closely.
Whitespace 1
• 4 spaces per indentation level.
• No hard tabs.
This is exactly what IDLE and the Emacs Python mode support. Other editors may also provide
this support.
Whitespace 2
• Add a space after "," in dicts, lists, tuples, & argument lists, and after ":" in dicts, but not
before.
• Put spaces around assignments & comparisons (except in argument lists).
• No spaces just inside parentheses or just before argument lists.
• No spaces just inside docstrings.
def make_squares(key, value=0):
"""Return a dictionary and a list..."""
d = {key: value}
l = [key, value]
return d, l
Naming
• joined_lower for functions, methods, attributes
But try to avoid the __private form. I never use it. Trust me. If you use it, you WILL regret it
later.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 5 of 32
Explanation:
People coming from a C++/Java background are especially prone to overusing/misusing this
"feature". But __private names don't work the same way as in Java or C++. They just trigger a
name mangling whose purpose is to prevent accidental namespace collisions in subclasses:
MyClass.__private just becomes MyClass._MyClass__private. (Note that even this breaks
down for subclasses with the same name as the superclass, e.g. subclasses in different modules.)
It is possible to access __private names from outside their class, just inconvenient and fragile
(it adds a dependency on the exact name of the superclass).
The problem is that the author of a class may legitimately think "this attribute/method name
should be private, only accessible from within this class definition" and use the
__privateconvention. But later on, a user of that class may make a subclass that legitimately
needs access to that name. So either the superclass has to be modified (which may be difficult
or impossible), or the subclass code has to use manually mangled names (which is ugly and
fragile at best).
There's a concept in Python: "we're all consenting adults here". If you use the __private form,
who are you protecting the attribute from? It's the responsibility of subclasses to use attributes
from superclasses properly, and it's the responsibility of superclasses to document their
attributes properly.
◦ http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually
-private
◦ http://stackoverflow.com/questions/1641219/does-python-have-private-variables-in-
classes
VeryLong.left_hand_side \
= even_longer.right_hand_side()
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 6 of 32
Backslashes are fragile; they must end the line they're on. If you add a space after the backslash, it
won't work any more. Also, they're ugly.
Long Strings
Adjacent literal strings are concatenated by the parser:
>>> print 'o' 'n' "e"
one
The spaces between literals are not required, but help with readability. Any type of quoting can be
used:
>>> print 't' r'\/\/' """o"""
t\/\/o
The string prefixed with an "r" is a "raw" string. Backslashes are not evaluated as escapes in raw
strings. They're useful for regular expressions and Windows filesystem paths.
>>> a = 'three'
>>> b = 'four'
>>> a b
File "<stdin>", line 1
a b
^
SyntaxError: invalid syntax
That's because this automatic concatenation is a feature of the Python parser/compiler, not the
interpreter. You must use the "+" operator to concatenate strings at run time.
text = ('Long strings can be made up '
'of several shorter strings.')
'''\
Triple
single
quotes\
'''
In the last example above (triple single quotes), note how the backslashes are used to escape the
newlines. This eliminates extra newlines, while keeping the text and quotes nicely left-justified. The
backslashes must be at the end of their lines.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 7 of 32
Compound Statements
Good:
if foo == 'blah':
do_something()
do_one()
do_two()
do_three()
Bad:
Whitespace & indentations are useful visual indicators of the program flow. The indentation of the
second "Good" line above shows the reader that something's going on, whereas the lack of indentation
in "Bad" hides the "if" statement.
Docstrings explain how to use code, and are for the usersof your code. Uses of docstrings:
• Explain the purpose of the function even if it seems obvious to you, because it might not be
obvious to someone else later on.
• Describe the parameters expected, the return values, and any exceptions raised.
• If the method is tightly coupled with a single caller, make some mention of the caller (though
be careful as the caller might change later).
Comments explain why, and are for the maintainers of your code. Examples include notes to
yourself, like:
# !!! BUG: ...
Both of these groups include you, so write good docstrings and comments!
Docstrings are useful in interactive use (help()) and for auto-documentation systems.
False comments & docstrings are worse than none at all. So keep them up to date! When you make
changes, make sure the comments & docstrings are consistent with the code, and don't contradict it.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 8 of 32
http://www.python.org/dev/peps/pep-0257/
But most importantly: know when to be inconsistent -- sometimes the style guide just
doesn't apply. When in doubt, use your best judgment. Look at other examples and decide
what looks best. And don't hesitate to ask!
1. When applying the rule would make the code less readable, even for someone who
is used to reading code that follows the rules.
2. To be consistent with surrounding code that also breaks it (maybe for historic
reasons) -- although this is also an opportunity to clean up someone else's mess (in
true XP style).
Idiom Potpourri
A selection of small, useful idioms.
We'll start with some easy ones and work our way up.
Swap Values
In other languages:
temp = a
a = b
b = temp
In Python:
b, a = a, b
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 9 of 32
Perhaps you've seen this before. But do you know how it works?
The right-hand side is unpacked into the names in the tuple on the left-hand side.
l (L) above is the list we just made (David's info). Sopeople is a list containing two items, each a 3-
item list.
>>> people = [l, ['Guido', 'BDFL', 'unlisted']]
>>> for (name, title, phone) in people:
... print name, phone
...
David +1-514-555-1234
Guido unlisted
Each item in people is being unpacked into the (name, title, phone) tuple.
Arbitrarily nestable (just be sure to match the structure on the left & right!):
>>> david, (gname, gtitle, gphone) = people
>>> gname
'Guido'
>>> gtitle
'BDFL'
>>> gphone
'unlisted'
>>> david
['David', 'Pythonista', '+1-514-555-1234']
The Python interpreter shows the parentheses for clarity, and I recommend you use parentheses too:
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 10 of 32
>>> (1,)
(1,)
In a one-tuple, the trailing comma is required; in 2+-tuples, the trailing comma is optional. In 0-tuples,
or empty tuples, a pair of parentheses is the shortcut syntax:
>>> ()
()
>>> tuple()
()
A common typo is to leave a comma even though you don't want a tuple. It can be easy to miss in
your code:
>>> value = 1,
>>> value
(1,)
So if you see a tuple where you don't expect one, look for a comma!
Interactive "_"
This is a really useful feature that surprisingly few people know.
In the interactive interpreter, whenever you evaluate an expression or call a function, the result is
bound to a temporary name, _(an underscore):
>>> 1 + 1
2
>>> _
2
It is especially useful when you're working out a problem interactively, and you want to store the
result for a later step:
>>> import math
>>> math.pi / 3
1.0471975511965976
>>> angle = _
>>> math.cos(angle)
0.50000000000000011
>>> _
0.50000000000000011
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 11 of 32
We want to join all the strings together into one large string. Especially when the number of
substrings is large...
Don't do this:
result = ''
for s in colors:
result += s
It has terrible memory usage and performance patterns. The "summation" will compute, store, and
then throw away each intermediate step.
Instead, do this:
result = ''.join(colors)
The join() string method does all the copying in one pass.
When you're only dealing with a few dozen or hundred strings, it won't make much difference. But
get in the habit of building strings efficiently, because with thousands or with loops, it will make a
difference.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 12 of 32
To make a nicely grammatical sentence, we want commas between all but the last pair of values,
where we want the word "or". The slice syntax does the job. The "slice until -1" ([:-1]) gives all but
the last value, which we join with comma-space.
Of course, this code wouldn't work with corner cases, lists of length 0 or 1.
Output:
Choose red, blue, green or yellow
If you need to compute the substrings incrementally, accumulate them in a list first:
items = []
...
items.append(item) # many times
...
# items is now complete
result = ''.join(fn(i) for i in items)
We accumulate the parts in a list so that we can apply the joinstring method, for efficiency.
• in is generally faster.
• This pattern also works for items in arbitrary containers (such as lists, tuples, and sets).
• in is also an operator (as we'll see).
Bad:
for key in d.keys():
print key
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 13 of 32
d.keys() creates a static list of the dictionary keys. Otherwise, you'll get an exception
"RuntimeError: dictionary changed size during iteration".
# not this:
if d.has_key(key):
...do something with d[key]
navs = {}
for (portfolio, equity, position) in data:
navs[portfolio] = (navs.get(portfolio, 0)
+ position * prices[equity])
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 14 of 32
else:
equities[portfolio] = [equity]
equities = {}
for (portfolio, equity) in data:
equities.setdefault(portfolio, []).append(
equity)
dict.setdefault() is equivalent to "get, or set & get". Or "set if necessary, then get". It's especially
efficient if your dictionary key is expensive to compute or long to type.
The only problem with dict.setdefault() is that the default value is always evaluated, whether
needed or not. That only matters if the default value is expensive to compute.
If the default value is expensive to compute, you may want to use the defaultdict class, which we'll
cover shortly.
The setdefault dictionary method returns the default value, but we ignore it here. We're taking
advantage of setdefault's side effect, that it sets the dictionary value only if there is no value
already.
defaultdict
New in Python 2.5.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 15 of 32
➔
import collections
d = collections.defaultdict(...)
Here's the example from earlier, where each dictionary value must be initialized to an empty list,
rewritten as with defaultdict:
from collections import defaultdict
equities = defaultdict(list)
for (portfolio, equity) in data:
equities[portfolio].append(equity)
There's no fumbling around at all now. In this case, the default factory function is list, which returns
an empty list.
This is how to get a dictionary with default values of 0: useint as a default factory function:
navs = defaultdict(int)
for (portfolio, equity, position) in data:
navs[portfolio] += position * prices[equity]
You should be careful with defaultdict though. You cannot getKeyError exceptions from properly
initialized defaultdict instances. You have to use a "key in dict" conditional if you need to check
for the existence of a specific key.
>>> pprint.pprint(pythons)
{'John': 'Cleese',
'Michael': 'Palin',
'Eric': 'Idle',
'Terry': 'Gilliam'}
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 16 of 32
Note that the order of the results of .keys() and .values() is different from the order of items when
constructing the dictionary. The order going in is different from the order coming out. This is because
a dictionary is inherently unordered. However, the order is guaranteed to be consistent (in other
words, the order of keys will correspond to the order of values), as long as the dictionary isn't changed
between calls.
It's elegant and efficient to take advantage of the intrinsic truth values (or Boolean values) of Python
objects.
Testing a list:
# do this: # not this:
if items: if len(items) != 0:
pass pass
Truth Values
The True and False names are built-in instances of typebool, Boolean values. Like None, there is
only one instance of each.
False True
False (== 0) True (== 1)
"" (empty string) any string but "" (" ","anything")
0, 0.0 any number but 0 (1, 0.1, -1, 3.14)
[], (), {}, set() any non-empty container ([0], (None,), [''])
None almost any object that's not explicitly False
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 17 of 32
To control the truth value of instances of a user-defined class, use the __nonzero__ or __len__
special methods. Use__len__ if your class is a container which has a length:
class MyContainer(object):
def __len__(self):
"""Return my length."""
return len(self.data)
def __nonzero__(self):
"""Return my truth value (True or False)."""
# This could be arbitrarily complex:
return bool(self.value)
In Python 3.0, __nonzero__ has been renamed to __bool__ for consistency with the bool built-in
type. For compatibility, add this to the class definition:
__bool__ = __nonzero__
Say we want to iterate over the items, and we need both the item's index and the item itself:
- or -
i = 0
for item in items: for i in range(len(items)):
print i, item print i, items[i]
i += 1
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 18 of 32
We need use a list wrapper to print the result becauseenumerate is a lazy function: it generates one
item, a pair, at a time, only when required. A for loop is one place that requires one result at a time.
enumerate is an example of agenerator, which we'll cover in greater detail later. printdoes not take
one result at a time -- we want the entire result, so we have to explicitly convert the generator into a
list when we print it.
# compare: # compare:
index = 0 for i in range(len(items)):
for item in items: print i, items[i]
print index, item
index += 1
The enumerate version is much shorter and simpler than the version on the left, and much easier to
read and understand than either.
An example showing how the enumerate function actually returns an iterator (a generator is a kind of
iterator):
>>> enumerate(items)
<enumerate object at 0x011EA1C0>
>>> e = enumerate(items)
>>> e.next()
(0, 'zero')
>>> e.next()
(1, 'one')
>>> e.next()
(2, 'two')
>>> e.next()
(3, 'three')
>>> e.next()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
StopIteration
Assigning another value to the same variable replaces the contents of the box:
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 19 of 32
a = 2;
Assigning one variable to another makes a copy of the value and puts it in the new box:
int b = a;
"b" is a second box, with a copy of integer 2. Box "a" has a separate copy.
The original integer 1 object no longer has a tag "a". It may live on, but we can't get to it through the
name "a". (When an object has no more references or tags, it is removed from memory.)
If we assign one name to another, we're just attaching another nametag to an existing object:
b = a
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 20 of 32
The name "b" is just a second tag bound to the same object as "a".
Although we commonly refer to "variables" even in Python (because it's common terminology), we
really mean "names" or "identifiers". In Python, "variables" are nametags for values, not labelled
boxes.
If you get nothing else out of this tutorial, I hope you understand how Python names work. A good
understanding is certain to pay dividends, helping you to avoid cases like this:
The problem here is that the default value of a_list, an empty list, is evaluated at function definition
time. So every time you call the function, you get the same default value. Try it several times:
>>> print bad_append('one')
['one']
Lists are a mutable objects; you can change their contents. The correct way to get a default list (or
dictionary, or set) is to create it at run time instead, inside the function:
def good_append(new_item, a_list=None):
if a_list is None:
a_list = []
a_list.append(new_item)
return a_list
% String Formatting
Python's % operator works like C's sprintf function.
Although if you don't know C, that's not very helpful. Basically, you provide a template or format and
interpolation values.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 21 of 32
In this example, the template contains two conversion specifications: "%s" means "insert a string
here", and "%i" means "convert an integer to a string and insert here". "%s" is particularly useful
because it uses Python's built-in str() function to to convert any object to a string.
The interpolation values must match the template; we have two values here, a tuple.
name = 'David'
messages = 3
text = ('Hello %s, you have %i messages'
% (name, messages))
print text
Output:
Details are in the Python Library Reference, section 2.3.6.2, "String Formatting Operations".
Bookmark this one!
If you haven't done it already, go to python.org, download the HTML documentation (in a .zip file or
a tarball), and install it on your machine. There's nothing like having the definitive resource at your
fingertips.
Here we specify the names of interpolation values, which are looked up in the supplied dictionary.
Notice any redundancy? The names "name" and "messages" are already defined in the local
namespace. We can take advantage of this.
This is very powerful. With this, you can do all the string formatting you want without having to
worry about matching the interpolation values to the template.
But power can be dangerous. ("With great power comes great responsibility.") If you use the locals
() form with an externally-supplied template string, you expose your entire local namespace to the
caller. This is just something to keep in mind.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 22 of 32
pprint is a very useful module. If you don't know it already, try playing with it. It makes debugging
your data structures much easier!
Note: Class attributes are in the class __dict__. Namespace lookups are actually chained dictionary
lookups.
List Comprehensions
List comprehensions ("listcomps" for short) are syntax shortcuts for this general pattern:
new_list = []
for item in a_list:
if condition(item):
new_list.append(fn(item))
As a list comprehension:
new_list = [fn(item) for item in a_list
if condition(item)]
Listcomps are clear & concise, up to a point. You can have multiple for-loops and if-conditions in a
listcomp, but beyond two or three total, or if the conditions are complex, I suggest that regular for
loops should be used. Applying the Zen of Python, choose the more readable way.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 23 of 32
As a loop:
total = 0
for num in range(1, 101):
total += num * num
We can use the sum function to quickly do the work for us, by building the appropriate sequence.
As a list comprehension:
total = sum([num * num for num in range(1, 101)])
As a generator expression:
Generator expressions ("genexps") are just like list comprehensions, except that where listcomps are
greedy, generator expressions are lazy. Listcomps compute the entire result list all at once, as a list.
Generator expressions compute one value at a time, when needed, as individual values. This is
especially useful for long sequences where the computed list is just an intermediate step and not the
final result.
In this case, we're only interested in the sum; we don't need the intermediate list of squares. We use
xrange for the same reason: it lazily produces values, one at a time.
The difference in syntax is that listcomps have square brackets, but generator expressions don't.
Generator expressions sometimes do require enclosing parentheses though, so you should always use
them.
Rule of thumb:
• Use a list comprehension when a computed list is the desired end result.
• Use a generator expression when the computed list is just an intermediate step.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 24 of 32
We needed a dictionary mapping month numbers (both as string and as integers) to month codes for
futures contracts. It can be done in one logical line of code.
Recent example:
month_codes = dict((fn(i+1), code)
for i, code in enumerate('FGHJKMNQUVXZ')
for fn in (int, str))
month_codes result:
{ 1: 'F', 2: 'G', 3: 'H', 4: 'J', ...
'1': 'F', '2': 'G', '3': 'H', '4': 'J', ...}
Sorting
It's easy to sort a list in Python:
a_list.sort()
(Note that the list is sorted in-place: the original list is sorted, and the sort method does not return the
list or a copy.)
But what if you have a list of data that you need to sort, but it doesn't sort naturally (i.e., sort on the
first column, then the second column, etc.)? You may need to sort on the second column first, then the
fourth column.
a_list.sort(custom_cmp)
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 25 of 32
* Note: DSU is often no longer necessary. See the next section,Sorting With Keys for the new
approach.
Instead of creating a custom comparison function, we create an auxiliary list that will sort naturally:
# Decorate:
to_sort = [(item[1], item[3], item)
for item in a_list]
# Sort:
to_sort.sort()
# Undecorate:
a_list = [item[-1] for item in to_sort]
The first line creates a list containing tuples: copies of the sort terms in priority order, followed by the
complete data record.
The second line does a native Python sort, which is very fast and efficient.
The third line retrieves the last value from the sorted list. Remember, this last value is the complete
data record. We're throwing away the sort terms, which have done their job and are no longer needed.
This is a tradeoff of space and complexity against time. Much simpler and faster, but we do need to
duplicate the original list.
to_sort.sort(key=my_key)
The function my_key will be called once for each item in theto_sort list.
You can make your own key function, or use any existing one-argument function if applicable:
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 26 of 32
Generators
We've already seen generator expressions. We can devise our own arbitrarily complex generators, as
functions:
def my_range_generator(stop):
value = 0
while value < stop:
yield value
value += 1
for i in my_range_generator(10):
do_something(i)
The yield keyword turns a function into a generator. When you call a generator function, instead of
running the code immediately Python returns a generator object, which is an iterator; it has anext
method. for loops just call the next method on the iterator, until a StopIteration exception is
raised. You can raise StopIteration explicitly, or implicitly by falling off the end of the generator
code as above.
Generators can simplify sequence/iterator handling, because we don't need to build concrete lists; just
compute one value at a time. The generator function maintains state.
This is how a for loop really works. Python looks at the sequence supplied after the in keyword. If
it's a simple container (such as a list, tuple, dictionary, set, or user-defined container) Python converts
it into an iterator. If it's already an iterator, Python uses it directly.
Then Python repeatedly calls the iterator's next method, assigns the return value to the loop counter
(i in this case), and executes the indented code. This is repeated over and over, until StopIteration
is raised, or a break statement is executed in the code.
A for loop can have an else clause, whose code is executed after the iterator runs dry, but not after a
breakstatement is executed. This distinction allows for some elegant uses. else clauses are not
always or often used on forloops, but they can come in handy. Sometimes an else clause perfectly
expresses the logic you need.
For example, if we need to check that a condition holds on some item, any item, in a sequence:
Example Generator
Filter out blank rows from a CSV reader (or items from a list):
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 27 of 32
def filter_rows(row_iterator):
for row in row_iterator:
if row:
yield row
This is possible because files support a next method, as do other iterators: lists, tuples, dictionaries
(for their keys), generators.
There is a caveat here: because of the way the buffering is done, you cannot mix .next & .read*
methods unless you're using Python 2.5+.
• Duck typing
If it walks like a duck, and talks like a duck, and looks like a duck: it's a duck. (Goose? Close
enough.)
• Exceptions
Use coercion if an object must be a particular type. If x must be a string for your code to work,
why not call
str(x)
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 28 of 32
try:
return str(x)
except TypeError:
...
Note: Always specify the exceptions to catch. Never use bareexcept clauses. Bare except clauses
will catch unexpected exceptions, making your code exceedingly difficult to debug.
Importing
from module import *
You've probably seen this "wild card" form of the import statement. You may even like it. Don't use
it.
LUKE: But how will I know why explicit imports are better than the wild-card form?
YODA: Know you will when your code you try to read six months from now.
Never!
The from module import * wild-card style leads to namespace pollution. You'll get things in your
local namespace that you didn't expect to get. You may see imported names obscuring module-
defined local names. You won't be able to figure out where certain names come from. Although a
convenient shortcut, this should not be in production code.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 29 of 32
Instead,
Note that this form doesn't lend itself to use in the interactive interpreter, where you may want to edit
and "reload()" a module.
When imported, a module's __name__ attribute is set to the module's file name, without ".py". So the
code guarded by theif statement above will not run when imported. When executed as a script
though, the __name__ attribute is set to "__main__", and the script code will run.
Except for special cases, you shouldn't put any major executable code at the top-level. Put code in
functions, classes, methods, and guard it with if __name__ == '__main__'.
Module Structure
"""module docstring"""
# imports
# constants
# exception classes
# interface functions
# classes
# internal functions & classes
def main(...):
...
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 30 of 32
if __name__ == '__main__':
status = main()
sys.exit(status)
Command-Line Processing
Example: cmdline.py:
#!/usr/bin/env python
"""
Module docstring.
"""
import sys
import optparse
def process_command_line(argv):
"""
Return a 2-tuple: (settings object, args list).
`argv` is a list of arguments, or `None` for ``sys.argv[1:]``.
"""
if argv is None:
argv = sys.argv[1:]
def main(argv=None):
settings, args = process_command_line(argv)
# application code here, like:
# run(settings, args)
return 0 # success
if __name__ == '__main__':
status = main()
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 31 of 32
sys.exit(status)
Packages
package/
__init__.py
module1.py
subpackage/
__init__.py
module2.py
Example:
import package.module1
from package.subpackage import module2
from package.subpackage.module2 import name
In Python 2.5 we now have absolute and relative imports via a future import:
from __future__ import absolute_import
I haven't delved into these myself yet, so we'll conveniently cut this discussion short.
http://cheeseshop.python.org/pypi
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013
Code Like a Pythonista: Idiomatic Python Page 32 of 32
References
• "Python Objects", Fredrik Lundh,http://www.effbot.org/zone/python-objects.htm
• "How to think like a Pythonista", Mark
Hammond,http://python.net/crew/mwh/hacks/objectthink.html
• "Python main() functions", Guido van Rossum,http://www.artima.com/weblogs/viewpost.jsp?
thread=4829
• "Python Idioms and Efficiency",http://jaynes.colorado.edu/PythonIdioms.html
• "Python track: python
idioms",http://www.cs.caltech.edu/courses/cs11/material/python/misc/python_idioms.html
• "Be Pythonic", Shalabh Chaturvedi,http://www.cafepy.com/article/be_pythonic/ (PDF version)
• "Python Is Not Java", Phillip J. Eby,http://dirtsimple.org/2004/12/python-is-not-java.html
• "What is Pythonic?", Martijn Faassen,http://faassen.n--tree.net/blog/view/weblog/2005/08/06/0
• "Sorting Mini-HOWTO", Andrew Dalke,http://wiki.python.org/moin/HowTo/Sorting
• "Python Idioms", http://www.gungfu.de/facts/wiki/Main/PythonIdioms
• "Python FAQs", http://www.python.org/doc/faq/
View document source. Generated on: 2012-12-26 20:38 UTC. Generated by Docutils from reStructuredText source.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 1/8/2013