except ImportError:

import StringIO

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

try:

import pickle

import cPickle as pickle

except ImportError:

import pickle

import __builtin__

import builtins

import copy_reg

import copyreg

import Queue

import queue

import SocketServer

import socketserver

import ConfigParser

import configparser

import repr

import reprlib

import commands

import subprocess

449

1. A common idiom in Python 2 was to try to import cStringIO as StringIO, and if that failed, to import

StringIO instead. Do not do this in Python 3; the io module does it for you. It will find the fastest

implementation available and use it automatically.

2. A similar idiom was used to import the fastest pickle implementation. Do not do this in Python 3; the

pickle module does it for you.

3. The builtins module contains the global functions, classes, and constants used throughout the Python

language. Redefining a function in the builtins module will redefine the global function everywhere. That is

exactly as powerful and scary as it sounds.

4. The copyreg module adds pickle support for custom types defined in C.

5. The queue module implements a multi-producer, multi-consumer queue.

6. The socketserver module provides generic base classes for implementing different kinds of socket servers.

7. The configparser module parses INI-style configuration files.

8. The reprlib module reimplements the built-in repr() function, with additional controls on how long the

representations can be before they are truncated.

9. The subprocess module allows you to spawn processes, connect to their pipes, and obtain their return

codes.

17.10. RELATIVE IMPORTS WITHIN A PACKAGE

A package is a group of related modules that function as a single entity. In Python 2, when modules within a

package need to reference each other, you use import foo or from foo import Bar. The Python 2

interpreter first searches within the current package to find foo.py, and then moves on to the other

directories in the Python search path (sys.path). Python 3 works a bit differently. Instead of searching the

current package, it goes directly to the Python search path. If you want one module within a package to

import another module in the same package, you need to explicitly provide the relative path between the

two modules.

Suppose you had this package, with multiple files in the same directory:

450

chardet/

|

+--__init__.py

|

+--constants.py

|

+--mbcharsetprober.py

|

+--universaldetector.py

Now suppose that universaldetector.py needs to import the entire constants.py file and one class from

mbcharsetprober.py. How do you do it?

Notes

Python 2

Python 3

import constants

from . import constants

from mbcharsetprober import

from .mbcharsetprober import

MultiByteCharSetProber

MultiByteCharsetProber

1. When you need to import an entire module from elsewhere in your package, use the new from . import

syntax. The period is actually a relative path from this file (universaldetector.py) to the file you want to

import (constants.py). In this case, they are in the same directory, thus the single period. You can also

import from the parent directory (from .. import anothermodule) or a subdirectory.

2. To import a specific class or function from another module directly into your module’s namespace, prefix

the target module with a relative path, minus the trailing slash. In this case, mbcharsetprober.py is in the

same directory as universaldetector.py, so the path is a single period. You can also import form the

parent directory (from ..anothermodule import AnotherClass) or a subdirectory.

17.11. next() ITERATOR METHOD

In Python 2, iterators had a next() method which returned the next item in the sequence. That’s still true

in Python 3, but there is now also a global next() function that takes an iterator as an argument.

Notes Python 2

Python 3

anIterator.next()

next(anIterator)

451

a_function_that_returns_an_iterator().next()

next(a_function_that_returns_an_iterator())

class A:

class A:

def next(self):

def __next__(self):

pass

pass

class A:

no change

def next(self, x, y):

pass

next = 42

next = 42

for an_iterator in a_sequence_of_iterators:

for an_iterator in a_sequence_of_iterators:

an_iterator.next()

an_iterator.__next__()

1. In the simplest case, instead of calling an iterator’s next() method, you now pass the iterator itself to the

global next() function.

2. If you have a function that returns an iterator, call the function and pass the result to the next() function.

(The 2to3 script is smart enough to convert this properly.)

3. If you define your own class and mean to use it as an iterator, define the __next__() special method.

4. If you define your own class and just happen to have a method named next() that takes one or more

arguments, 2to3 will not touch it. This class can not be used as an iterator, because its next() method

takes arguments.

5. This one is a bit tricky. If you have a local variable named next, then it takes precedence over the new

global next() function. In this case, you need to call the iterator’s special __next__() method to get the

next item in the sequence. (Alternatively, you could also refactor the code so the local variable wasn’t

named next, but 2to3 will not do that for you automatically.)

17.12. filter() GLOBAL FUNCTION

In Python 2, the filter() function returned a list, the result of filtering a sequence through a function that

returned True or False for each item in the sequence. In Python 3, the filter() function returns an

iterator, not a list.

Notes

Python 2

Python 3

filter(a_function, a_sequence)

list(filter(a_function, a_sequence))

list(filter(a_function, a_sequence))

no change

filter(None, a_sequence)

[i for i in a_sequence if i]

452

for i in filter(None, a_sequence):

no change

[i for i in filter(a_function,

no change

a_sequence)]

1. In the most basic case, 2to3 will wrap a call to filter() with a call to list(), which simply iterates

through its argument and returns a real list.

2. However, if the call to filter() is already wrapped in list(), 2to3 will do nothing, since the fact that

filter() is returning an iterator is irrelevant.

3. For the special syntax of filter(None, ...), 2to3 will transform the call into a semantically equivalent list

comprehension.

4. In contexts like for loops, which iterate through the entire sequence anyway, no changes are necessary.

5. Again, no changes are necessary, because the list comprehension will iterate through the entire sequence,

and it can do that just as well if filter() returns an iterator as if it returns a list.

17.13. map() GLOBAL FUNCTION

In much the same way as filter(), the map() function now returns an iterator. (In Python 2, it returned a list.)

Notes

Python 2

Python 3

map(a_function, 'PapayaWhip')

list(map(a_function, 'PapayaWhip'))

map(None, 'PapayaWhip')

list('PapayaWhip')

map(lambda x: x+1, range(42))

[x+1 for x in range(42)]

for i in map(a_function, a_sequence):

no change

[i for i in map(a_function,

no change

a_sequence)]

1. As with filter(), in the most basic case, 2to3 will wrap a call to map() with a call to list().

2. For the special syntax of map(None, ...), the identity function, 2to3 will convert it to an equivalent call to

list().

3. If the first argument to map() is a lambda function, 2to3 will convert it to an equivalent list comprehension.

4. In contexts like for loops, which iterate through the entire sequence anyway, no changes are necessary.

5. Again, no changes are necessary, because the list comprehension will iterate through the entire sequence,

and it can do that just as well if map() returns an iterator as if it returns a list.

453

17.14. reduce() GLOBAL FUNCTION

In Python 3, the reduce() function has been removed from the global namespace and placed in the

functools module.

Notes

Python 2

Python 3

reduce(a, b, c)

from functools import reduce

reduce(a, b, c)

17.15. apply() GLOBAL FUNCTION

Python 2 had a global function called apply(), which took a function f and a list [a, b, c] and returned

f(a, b, c). You can accomplish the same thing by calling the function directly and passing it the list of

arguments preceded by an asterisk. In Python 3, the apply() function no longer exists; you must use the

asterisk notation.

Notes

Python 2

Python 3

apply(a_function, a_list_of_args)

a_function(*a_list_of_args)

apply(a_function, a_list_of_args,

a_function(*a_list_of_args,

a_dictionary_of_named_args)

**a_dictionary_of_named_args)

apply(a_function, a_list_of_args + z)

a_function(*a_list_of_args + z)

apply(aModule.a_function,

aModule.a_function(*a_list_of_args)

a_list_of_args)

1. In the simplest form, you can call a function with a list of arguments (an actual list like [a, b, c]) by

prepending the list with an asterisk (*). This is exactly equivalent to the old apply() function in Python 2.

2. In Python 2, the apply() function could actually take three parameters: a function, a list of arguments, and a

dictionary of named arguments. In Python 3, you can accomplish the same thing by prepending the list of

arguments with an asterisk (*) and the dictionary of named arguments with two asterisks (**).

3. The + operator, used here for list concatenation, takes precedence over the * operator, so there is no need

for extra parentheses around a_list_of_args + z.

4. The 2to3 script is smart enough to convert complex apply() calls, including calling functions within

imported modules.

454

17.16. intern() GLOBAL FUNCTION

In Python 2, you could call the intern() function on a string to intern it as a performance optimization. In

Python 3, the intern() function has been moved to the sys module.

Notes

Python 2

Python 3

intern(aString)

sys.intern(aString)

17.17. exec STATEMENT

Just as the print statement became a function in Python 3, so too has the exec statement. The exec() function takes a string which contains arbitrary Python code and executes it as if it were just another

statement or expression. exec() is like eval(), but even more powerful and evil. The eval() function can only evaluate a single expression, but exec() can execute multiple statements, imports, function

declarations — essentially an entire Python program in a string.

Notes

Python 2

Python 3

exec codeString

exec(codeString)

exec codeString in a_global_namespace

exec(codeString, a_global_namespace)

exec codeString in a_global_namespace,

exec(codeString, a_global_namespace,

a_local_namespace

a_local_namespace)

1. In the simplest form, the 2to3 script simply encloses the code-as-a-string in parentheses, since exec() is

now a function instead of a statement.

2. The old exec statement could take a namespace, a private environment of globals in which the code-as-a-

string would be executed. Python 3 can also do this; just pass the namespace as the second argument to the

exec() function.

3. Even fancier, the old exec statement could also take a local namespace (like the variables defined within a

function). In Python 3, the exec() function can do that too.

17.18. execfile STATEMENT

Like the old exec statement, the old execfile statement will execute strings as if they were Python code.

Where exec took a string, execfile took a filename. In Python 3, the execfile statement has been

455

eliminated. If you really need to take a file of Python code and execute it (but you’re not willing to simply

import it), you can accomplish the same thing by opening the file, reading its contents, calling the global

compile() function to force the Python interpreter to compile the code, and then call the new exec()

function.

Notes

Python 2

Python 3

execfile('a_filename')

exec(compile(open('a_filename').read(),

'a_filename', 'exec'))

17.19. repr LITERALS (BACKTICKS)

In Python 2, there was a special syntax of wrapping any object in backticks (likèx`) to get a representation

of the object. In Python 3, this capability still exists, but you can no longer use backticks to get it. Instead,

use the global repr() function.

Notes

Python 2

Python 3

`x`

repr(x)

`'PapayaWhip' + `2``

repr('PapayaWhip' + repr(2))

1. Remember, x can be anything — a class, a function, a module, a primitive data type, & c. The repr()

function works on everything.

2. In Python 2, backticks could be nested, leading to this sort of confusing (but valid) expression. The 2to3 tool

is smart enough to convert this into nested calls to repr().

17.20. try...except STATEMENT

The syntax for catching exceptions has changed slightly between Python 2 and Python 3.

Notes

Python 2

Python 3

try:

try:

import mymodule

import mymodule

except ImportError, e

except ImportError as e:

pass

pass

456

try:

try:

import mymodule

import mymodule

except (RuntimeError, ImportError), e

except (RuntimeError, ImportError) as e:

pass

pass

try:

no change

import mymodule

except ImportError:

pass

try:

no change

import mymodule

except:

pass

1. Instead of a comma after the exception type, Python 3 uses a new keyword, as.

2. The as keyword also works for catching multiple types of exceptions at once.

3. If you catch an exception but don’t actually care about accessing the exception object itself, the syntax is

identical between Python 2 and Python 3.

4. Similarly, if you use a fallback to catch all exceptions, the syntax is identical.

☞ You should never use a fallback to catch all exceptions when importing modules (or

most other times). Doing so will catch things like KeyboardInterrupt (if the user

pressed Ctrl-C to interrupt the program) and can make it more difficult to debug

errors.

17.21. raise STATEMENT

The syntax for raising your own exceptions has changed slightly between Python 2 and Python 3.

Notes

Python 2

Python 3

raise MyException

unchanged

raise MyException, 'error message'

raise MyException('error message')

457

raise MyException, 'error message',

raise MyException('error

a_traceback

message').with_traceback(a_traceback)

raise 'error message'

unsupported

1. In the simplest form, raising an exception without a custom error message, the syntax is unchanged.

2. The change becomes noticeable when you want to raise an exception with a custom error message. Python

2 separated the exception class and the message with a comma; Python 3 passes the error message as a

parameter.

3. Python 2 supported a more complex syntax to raise an exception with a custom traceback (stack trace).

You can do this in Python 3 as well, but the syntax is quite different.

4. In Python 2, you could raise an exception with no exception class, just an error message. In Python 3, this is

no longer possible. 2to3 will warn you that it was unable to fix this automatically.

17.22. throw METHOD ON GENERATORS

In Python 2, generators have a throw() method. Calling a_generator.throw() raises an exception at the

point where the generator was paused, then returns the next value yielded by the generator function. In

Python 3, this functionality is still available, but the syntax is slightly different.

Notes

Python 2

Python 3

a_generator.throw(MyException)

no change

a_generator.throw(MyException, 'error

a_generator.throw(MyException('error

message')

message'))

a_generator.throw('error message')

unsupported

1. In the simplest form, a generator throws an exception without a custom error message. In this case, the

syntax has not changed between Python 2 and Python 3.

2. If the generator throws an exception with a custom error message, you need to pass the error string to the

exception when you create it.

3. Python 2 also supported throwing an exception with only a custom error message. Python 3 does not

support this, and the 2to3 script will display a warning telling you that you will need to fix this code

manually.

458

17.23. xrange() GLOBAL FUNCTION

In Python 2, there were two ways to get a range of numbers: range(), which returned a list, and xrange(),

which returned an iterator. In Python 3, range() returns an iterator, and xrange() doesn’t exist.

Notes

Python 2

Python 3

xrange(10)

range(10)

a_list = range(10)

a_list = list(range(10))

[i for i in xrange(10)]

[i for i in range(10)]

for i in range(10):

no change

sum(range(10))

no change

1. In the simplest case, the 2to3 script will simply convert xrange() to range().

2. If your Python 2 code used range(), the 2to3 script does not know whether you needed a list, or whether

an iterator would do. It errs on the side of caution and coerces the return value into a list by calling the

list() function.

3. If the xrange() function was inside a list comprehension, the 2to3 script is clever enough not to wrap the

range() function with a call to list(). The list comprehension will work just fine with the iterator that the

range() function returns.

4. Similarly, a for loop will work just fine with an iterator, so there is no need to change anything here.

5. The sum() function will also work with an iterator, so 2to3 makes no changes here either. Like dictionary

methods that return views instead of lists, this applies to min(), max(), sum(), list(), tuple(), set(), sorted(), any(), and all().

17.24. raw_input() AND input() GLOBAL FUNCTIONS

Python 2 had two global functions for asking the user for input on the command line. The first, called

input(), expected the user to enter a Python expression (and returned the result). The second, called

raw_input(), just returned whatever the user typed. This was wildly confusing for beginners and widely

regarded as a “wart” in the language. Python 3 excises this wart by renaming raw_input() to input(), so it

works the way everyone naively expects it to work.

Notes

Python 2

Python 3

raw_input()

input()

459

raw_input('prompt')

input('prompt')

input()

eval(input())

1. In the simplest form, raw_input() becomes input().

2. In Python 2, the raw_input() function could take a prompt as a parameter. This has been retained in

Python 3.

3. If you actually need to ask the user for a Python expression to evaluate, use the input() function and pass

the result to eval().

17.25. func_* FUNCTION ATTRIBUTES

In Python 2, code within functions can access special attributes about the function itself. In Python 3, these

special function attributes have been renamed for consistency with other attributes.

Notes

Python 2

Python 3

a_function.func_name

a_function.__name__

a_function.func_doc

a_function.__doc__

a_function.func_defaults

a_function.__defaults__

a_function.func_dict

a_function.__dict__

a_function.func_closure

a_function.__closure__

a_function.func_globals

a_function.__globals__

a_function.func_code

a_function.__code__

1. The __name__ attribute (previously func_name) contains the function’s name.

2. The __doc__ attribute (previously func_doc) contains the docstring that you defined in the function’s source

code.

3. The __defaults__ attribute (previously func_defaults) is a tuple containing default argument values for

those arguments that have default values.

4. The __dict__ attribute (previously func_dict) is the namespace supporting arbitrary function attributes.

5. The __closure__ attribute (previously func_closure) is a tuple of cells that contain bindings for the

function’s free variables.

6. The __globals__ attribute (previously func_globals) is a reference to the global namespace of the module

in which the function was defined.

7. The __code__ attribute (previously func_code) is a code object representing the compiled function body.

460

17.26. xreadlines() I/O METHOD

In Python 2, file objects had an xreadlines() method which returned an iterator that would read the file

one line at a time. This was useful in for loops, among other places. In fact, it was so useful, later versions

of Python 2 added the capability to file objects themselves.

In Python 3, the xreadlines() method no longer exists. 2to3 can fix the simple cases, but some edge cases

will require manual intervention.

Notes

Python 2

Python 3

for line in a_file.xreadlines():

for line in a_file:

for line in a_file.xreadlines(5):

no change (broken)

1. If you used to call xreadlines() with no arguments, 2to3 will convert it to just the file object. In Python 3,

this will accomplish the same thing: read the file one line at a time and execute the body of the for loop.

2. If you used to call xreadlines() with an argument (the number of lines to read at a time), 2to3 will not fix

it, and your code will fail with an AttributeError: '_io.TextIOWrapper' object has no attribute

'xreadlines'. You can manually change xreadlines() to readlines() to get it to work in Python 3. (The

readlines() method now returns an iterator, so it is just as efficient as xreadlines() was in Python 2.)

?

17.27. lambda FUNCTIONS THAT TAKE A TUPLE INSTEAD OF MULTIPLE

PARAMETERS

In Python 2, you could define anonymous lambda functions which took multiple parameters by defining the

function as taking a tuple with a specific number of items. In effect, Python 2 would “unpack” the tuple into

named arguments, which you could then reference (by name) within the lambda function. In Python 3, you

can still pass a tuple to a lambda function, but the Python interpreter will not unpack the tuple into named

arguments. Instead, you will need to reference each argument by its positional index.

Notes

Python 2

Python 3

lambda (x,): x + f(x)

lambda x1: x1[0] + f(x1[0])

461

lambda (x, y): x + f(y)

lambda x_y: x_y[0] + f(x_y[1])

lambda (x, (y, z)): x + y + z

lambda x_y_z: x_y_z[0] + x_y_z[1][0] +

x_y_z[1][1]

lambda x, y, z: x + y + z

unchanged

1. If you had defined a lambda function that took a tuple of one item, in Python 3 that would become a

lambda with references to x1[0]. The name x1 is autogenerated by the 2to3 script, based on the named

arguments in the original tuple.

2. A lambda function with a two-item tuple (x, y) gets converted to x_y with positional arguments x_y[0]

and x_y[1].

3. The 2to3 script can even handle lambda functions with nested tuples of named arguments. The resulting

Python 3 code is a bit unreadable, but it works the same as the old code did in Python 2.

4. You can define lambda functions that take multiple arguments. Without parentheses around the arguments,

Python 2 just treats it as a lambda function with multiple arguments; within the lambda function, you simply

reference the arguments by name, just like any other function. This syntax still works in Python 3.

17.28. SPECIAL METHOD ATTRIBUTES

In Python 2, class methods can reference the class object in which they are defined, as well as the method

object itself. im_self is the class instance object; im_func is the function object; im_class is the class of

im_self. In Python 3, these special method attributes have been renamed to follow the naming conventions

of other attributes.

Notes Python 2

Python 3

aClassInstance.aClassMethod.im_func

aClassInstance.aClassMethod.__func__

aClassInstance.aClassMethod.im_self

aClassInstance.aClassMethod.__self__

aClassInstance.aClassMethod.im_class

aClassInstance.aClassMethod.__self__.__class__

17.29. __nonzero__ SPECIAL METHOD

In Python 2, you could build your own classes that could be used in a boolean context. For example, you

could instantiate the class and then use the instance in an if statement. To do this, you defined a special

__nonzero__() method which returned True or False, and it was called whenever the instance was used in

462

a boolean context. In Python 3, you can still do this, but the name of the method has changed to

__bool__().

Notes

Python 2

Python 3

class A:

class A:

def __nonzero__(self):

def __bool__(self):

pass

pass

class A:

no change

def __nonzero__(self, x, y):

pass

1. Instead of __nonzero__(), Python 3 calls the __bool__() method when evaluating an instance in a boolean

context.

2. However, if you have a __nonzero__() method that takes arguments, the 2to3 tool will assume that you

were using it for some other purpose, and it will not make any changes.

17.30. OCTAL LITERALS

The syntax for defining base 8 (octal) numbers has changed slightly between Python 2 and Python 3.

Notes

Python 2

Python 3

x = 0755

x = 0o755

17.31. sys.maxint

Due to the integration of the long and int types, the sys.maxint constant is no longer accurate. Because the value may still be useful in determining platform-specific capabilities, it has been retained but renamed as

sys.maxsize.

Notes

Python 2

Python 3

from sys import maxint

from sys import maxsize

a_function(sys.maxint)

a_function(sys.maxsize)

1. maxint becomes maxsize.

463

2. Any usage of sys.maxint becomes sys.maxsize.

17.32. callable() GLOBAL FUNCTION

In Python 2, you could check whether an object was callable (like a function) with the global callable()

function. In Python 3, this global function has been eliminated. To check whether an object is callable, check

for the existence of the __call__() special method.

Notes

Python 2

Python 3

callable(anything)

hasattr(anything, '__call__')

17.33. zip() GLOBAL FUNCTION

In Python 2, the global zip() function took any number of sequences and returned a list of tuples. The first

tuple contained the first item from each sequence; the second tuple contained the second item from each

sequence; and so on. In Python 3, zip() returns an iterator instead of a list.

Notes

Python 2

Python 3

zip(a, b, c)

list(zip(a, b, c))

d.join(zip(a, b, c))

no change

1. In the simplest form, you can get the old behavior of the zip() function by wrapping the return value in a

call to list(), which will run through the iterator that zip() returns and return a real list of the results.

2. In contexts that already iterate through all the items of a sequence (such as this call to the join() method),

the iterator that zip() returns will work just fine. The 2to3 script is smart enough to detect these cases

and make no change to your code.

17.34. StandardError EXCEPTION

In Python 2, StandardError was the base class for all built-in exceptions other than StopIteration,

GeneratorExit, KeyboardInterrupt, and SystemExit. In Python 3, StandardError has been eliminated;

use Exception instead.

Notes

Python 2

Python 3

464

x = StandardError()

x = Exception()

x = StandardError(a, b, c)

x = Exception(a, b, c)

17.35. types MODULE CONSTANTS

The types module contains a variety of constants to help you determine the type of an object. In Python 2,

it contained constants for all primitive types like dict and int. In Python 3, these constants have been

eliminated; just use the primitive type name instead.

Notes

Python 2

Python 3

types.UnicodeType

str

types.StringType

bytes

types.DictType

dict

types.IntType

int

types.LongType

int

types.ListType

list

types.NoneType

type(None)

types.BooleanType

bool

types.BufferType

memoryview

types.ClassType

type

types.ComplexType

complex

types.EllipsisType

type(Ellipsis)

types.FloatType

float

types.ObjectType

object

types.NotImplementedType

type(NotImplemented)

types.SliceType

slice

types.TupleType

tuple

types.TypeType

type

types.XRangeType

range

465

types.StringType gets mapped to bytes instead of str because a Python 2 “string”

(not a Unicode string, just a regular string) is really just a sequence of bytes in a

particular character encoding.

17.36. isinstance() GLOBAL FUNCTION

The isinstance() function checks whether an object is an instance of a particular class or type. In Python

2, you could pass a tuple of types, and isinstance() would return True if the object was any of those

types. In Python 3, you can still do this, but passing the same type twice is deprecated.

Notes

Python 2

Python 3

isinstance(x, (int, float, int))

isinstance(x, (int, float))

17.37. basestring DATATYPE

Python 2 had two string types: Unicode and non-Unicode. But there was also another type, basestring. It

was an abstract type, a superclass for both the str and unicode types. It couldn’t be called or instantiated

directly, but you could pass it to the global isinstance() function to check whether an object was either a

Unicode or non-Unicode string. In Python 3, there is only one string type, so basestring has no reason to

exist.

Notes

Python 2

Python 3

isinstance(x, basestring)

isinstance(x, str)

17.38. itertools MODULE

Python 2.3 introduced the itertools module, which defined variants of the global zip(), map(), and

filter() functions that returned iterators instead of lists. In Python 3, those global functions return

iterators, so those functions in the itertools module have been eliminated. (There are still lots of useful

functions in the itertools module, just not these.)

Notes

Python 2

Python 3

itertools.izip(a, b)

zip(a, b)

466

itertools.imap(a, b)

map(a, b)

itertools.ifilter(a, b)

filter(a, b)

from itertools import imap, izip, foo

from itertools import foo

1. Instead of itertools.izip(), just use the global zip() function.

2. Instead of itertools.imap(), just use map().

3. itertools.ifilter() becomes filter().

4. The itertools module still exists in Python 3, it just doesn’t have the functions that have migrated to the

global namespace. The 2to3 script is smart enough to remove the specific imports that no longer exist,

while leaving other imports intact.

17.39. sys.exc_type, sys.exc_value, sys.exc_traceback

Python 2 had three variables in the sys module that you could access while an exception was being handled:

sys.exc_type, sys.exc_value, sys.exc_traceback. (Actually, these date all the way back to Python 1.)

Ever since Python 1.5, these variables have been deprecated in favor of sys.exc_info(), which is a function

that returns a tuple containing those three values. In Python 3, these individual variables have finally gone

away; you must use the sys.exc_info() function.

Notes

Python 2

Python 3

sys.exc_type

sys.exc_info()[0]

sys.exc_value

sys.exc_info()[1]

sys.exc_traceback

sys.exc_info()[2]

17.40. LIST COMPREHENSIONS OVER TUPLES

In Python 2, if you wanted to code a list comprehension that iterated over a tuple, you did not need to put

parentheses around the tuple values. In Python 3, explicit parentheses are required.

Notes

Python 2

Python 3

[i for i in 1, 2]

[i for i in (1, 2)]

467

17.41. os.getcwdu() FUNCTION

Python 2 had a function named os.getcwd(), which returned the current working directory as a (non-

Unicode) string. Because modern file systems can handle directory names in any character encoding, Python

2.3 introduced os.getcwdu(). The os.getcwdu() function returned the current working directory as a

Unicode string. In Python 3, there is only one string type (Unicode), so os.getcwd() is all you need.

Notes

Python 2

Python 3

os.getcwdu()

os.getcwd()

17.42. METACLASSES

In Python 2, you could create metaclasses either by defining the metaclass argument in the class

declaration, or by defining a special class-level __metaclass__ attribute. In Python 3, the class-level attribute

has been eliminated.

Notes Python 2

Python 3

class C(metaclass=PapayaMeta):

unchanged

pass

class Whip:

class Whip(metaclass=PapayaMeta):

__metaclass__ = PapayaMeta

pass

class C(Whipper, Beater):

class C(Whipper, Beater, metaclass=PapayaMeta):

__metaclass__ = PapayaMeta

pass

1. Declaring the metaclass in the class declaration worked in Python 2, and it still works the same in Python 3.

2. Declaring the metaclass in a class attribute worked in Python 2, but doesn’t work in Python 3.

3. The 2to3 script is smart enough to construct a valid class declaration, even if the class is inherited from one

or more base classes.

17.43. MATTERS OF STYLE

The rest of the “fixes” listed here aren’t really fixes per se. That is, the things they change are matters of

style, not substance. They work just as well in Python 3 as they do in Python 2, but the developers of

Python have a vested interest in making Python code as uniform as possible. To that end, there is an official

468

Python style guide which outlines — in excruciating detail — all sorts of nitpicky details that you almost certainly don’t care about. And given that 2to3 provides such a great infrastructure for converting Python

code from one thing to another, the authors took it upon themselves to add a few optional features to

improve the readability of your Python programs.

17.43.1. set() LITERALS (EXPLICIT)

In Python 2, the only way to define a literal set in your code was to call set(a_sequence). This still works

in Python 3, but a clearer way of doing it is to use the new set literal notation: curly braces. This works for

everything except empty sets, because dictionaries also use curly braces, so {} is an empty dictionary, not an

empty set.

☞ The 2to3 script will not fix set() literals by default. To enable this fix, specify -f

set_literal on the command line when you call 2to3.

Notes

Before

After

set([1, 2, 3])

{1, 2, 3}

set((1, 2, 3))

{1, 2, 3}

set([i for i in a_sequence])

{i for i in a_sequence}

17.43.2. buffer() GLOBAL FUNCTION (EXPLICIT)

Python objects implemented in C can export a “buffer interface,” which allows other Python code to directly

read and write a block of memory. (That is exactly as powerful and scary as it sounds.) In Python 3,

buffer() has been renamed to memoryview(). (It’s a little more complicated than that, but you can almost

certainly ignore the differences.)

☞ The 2to3 script will not fix the buffer() function by default. To enable this fix,

specify -f buffer on the command line when you call 2to3.

469

Notes

Before

After

x = buffer(y)

x = memoryview(y)

17.43.3. WHITESPACE AROUND COMMAS (EXPLICIT)

Despite being draconian about whitespace for indenting and outdenting, Python is actually quite liberal about

whitespace in other areas. Within lists, tuples, sets, and dictionaries, whitespace can appear before and after

commas with no ill effects. However, the Python style guide states that commas should be preceded by zero

spaces and followed by one. Although this is purely an aesthetic issue (the code works either way, in both

Python 2 and Python 3), the 2to3 script can optionally fix this for you.

☞ The 2to3 script will not fix whitespace around commas by default. To enable this fix,

specify -f wscomma on the command line when you call 2to3.

Notes

Before

After

a ,b

a, b

{a :b}

{a: b}

17.43.4. COMMON IDIOMS (EXPLICIT)

There were a number of common idioms built up in the Python community. Some, like the while 1: loop,

date back to Python 1. (Python didn’t have a true boolean type until version 2.3, so developers used 1 and 0

instead.) Modern Python programmers should train their brains to use modern versions of these idioms

instead.

☞ The 2to3 script will not fix common idioms by default. To enable this fix, specify -f

idioms on the command line when you call 2to3.

Notes

Before

After

470

while 1:

while True:

do_stuff()

do_stuff()

type(x) == T

isinstance(x, T)

type(x) is T

isinstance(x, T)

a_list = list(a_sequence)

a_list = sorted(a_sequence)

a_list.sort()

do_stuff(a_list)

do_stuff(a_list)

471

CHAPTER 18. SPECIAL METHOD NAMES

My specialty is being right when other people are wrong.

George Bernard Shaw

18.1. DIVING IN

Throughoutthisbook,you’veseenexamplesof“specialmethods”—certain“magic”methodsthat

Python invokes when you use certain syntax. Using special methods, your classes can act like sets, like

dictionaries, like functions, like iterators, or even like numbers. This appendix serves both as a reference for

the special methods we’ve seen already and a brief introduction to some of the more esoteric ones.

18.2. BASICS

If you’ve read the introduction to classes, you’ve already seen the most common special method: the __init__() method. The majority of classes I write end up needing some initialization. There are also a few

other basic special methods that are especially useful for debugging your custom classes.

Notes You Want…

So You Write…

And Python Calls…

to initialize an instance

x = MyClass()

x.__init__()

the “official” representation as

repr(x)

x.__repr__()

a string

the “informal” value as a string

str(x)

x.__str__()

the “informal” value as a byte

bytes(x)

x.__bytes__()

array

the value as a formatted string

format(x, format_spec)

x.__format__(format_spec)

1. The __init__() method is called after the instance is created. If you want to control the actual creation

process, use the __new__() method.

2. By convention, the __repr__() method should return a string that is a valid Python expression.

472

3. The __str__() method is also called when you print(x).

4. New in Python 3, since the bytes type was introduced.

5. By convention, format_spec should conform to the Format Specification Mini-Language. decimal.py in the Python standard library provides its own __format__() method.

18.3. CLASSES THAT ACT LIKE ITERATORS

In the Iterators chapter, you saw how to build an iterator from the ground up using the __iter__() and __next__() methods.

Notes You Want…

So You Write…

And Python

Calls…

to iterate through a sequence

iter(seq)

seq.__iter__()

to get the next value from an

next(seq)

seq.__next__()

iterator

to create an iterator in reverse

reversed(seq)

seq.__reversed__()

order

1. The __iter__() method is called whenever you create a new iterator. It’s a good place to initialize the

iterator with initial values.

2. The __next__() method is called whenever you retrieve the next value from an iterator.

3. The __reversed__() method is uncommon. It takes an existing sequence and returns an iterator that yields

the items in the sequence in reverse order, from last to first.

As you saw in the Iterators chapter, a for loop can act on an iterator. In this loop:

for x in seq:

print(x)

Python 3 will call seq.__iter__() to create an iterator, then call the __next__() method on that iterator

to get each value of x. When the __next__() method raises a StopIteration exception, the for loop ends

gracefully.

473

18.4. COMPUTED ATTRIBUTES

Notes You Want…

So You Write…

And Python Calls…

to get a computed

x.my_property

x.__getattribute__('my_property')

attribute (unconditionally)

to get a computed

x.my_property

x.__getattr__('my_property')

attribute (fallback)

to set an attribute

x.my_property = value

x.__setattr__('my_property',

value)

to delete an attribute

del x.my_property

x.__delattr__('my_property')

to list all attributes and

dir(x)

x.__dir__()

methods

1. If your class defines a __getattribute__() method, Python will call it on every reference to any attribute or

method name (except special method names, since that would cause an unpleasant infinite loop).

2. If your class defines a __getattr__() method, Python will call it only after looking for the attribute in all

the normal places. If an instance x defines an attribute color, x.color will not call

x.__getattr__('color'); it will simply return the already-defined value of x.color.

3. The __setattr__() method is called whenever you assign a value to an attribute.

4. The __delattr__() method is called whenever you delete an attribute.

5. The __dir__() method is useful if you define a __getattr__() or __getattribute__() method. Normally,

calling dir(x) would only list the regular attributes and methods. If your __getattr__() method handles a

color attribute dynamically, dir(x) would not list color as one of the available attributes. Overriding the

__dir__() method allows you to list color as an available attribute, which is helpful for other people who

wish to use your class without digging into the internals of it.

The distinction between the __getattr__() and __getattribute__() methods is subtle but important. I

can explain it with two examples:

474

class Dynamo:

def __getattr__(self, key):

if key == 'color':

return 'PapayaWhip'

else:

raise AttributeError

>>> dyn = Dynamo()

>>> dyn.color

'PapayaWhip'

>>> dyn.color = 'LemonChiffon'

>>> dyn.color

'LemonChiffon'

1. The attribute name is passed into the __getattr__() method as a string. If the name is 'color', the

method returns a value. (In this case, it’s just a hard-coded string, but you would normally do some sort of

computation and return the result.)

2. If the attribute name is unknown, the __getattr__() method needs to raise an AttributeError exception,

otherwise your code will silently fail when accessing undefined attributes. (Technically, if the method doesn’t

raise an exception or explicitly return a value, it returns None, the Python null value. This means that all

attributes not explicitly defined will be None, which is almost certainly not what you want.)

3. The dyn instance does not have an attribute named color, so the __getattr__() method is called to

provide a computed value.

4. After explicitly setting dyn.color, the __getattr__() method will no longer be called to provide a value

for dyn.color, because dyn.color is already defined on the instance.

On the other hand, the __getattribute__() method is absolute and unconditional.

475

class SuperDynamo:

def __getattribute__(self, key):

if key == 'color':

return 'PapayaWhip'

else:

raise AttributeError

>>> dyn = SuperDynamo()

>>> dyn.color

'PapayaWhip'

>>> dyn.color = 'LemonChiffon'

>>> dyn.color

'PapayaWhip'

1. The __getattribute__() method is called to provide a value for dyn.color.

2. Even after explicitly setting dyn.color, the __getattribute__() method is still called to provide a value for

dyn.color. If present, the __getattribute__() method is called unconditionally for every attribute and

method lookup, even for attributes that you explicitly set after creating an instance.

☞ If your class defines a __getattribute__() method, you probably also want to

define a __setattr__() method and coordinate between them to keep track of

attribute values. Otherwise, any attributes you set after creating an instance will

disappear into a black hole.

You need to be extra careful with the __getattribute__() method, because it is also called when Python

looks up a method name on your class.

476

class Rastan:

def __getattribute__(self, key):

raise AttributeError

def swim(self):

pass

>>> hero = Rastan()

>>> hero.swim()

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

File "<stdin>", line 3, in __getattribute__

AttributeError

1. This class defines a __getattribute__() method which always raises an AttributeError exception. No

attribute or method lookups will succeed.

2. When you call hero.swim(), Python looks for a swim() method in the Rastan class. This lookup goes

through the __getattribute__() method, because all attribute and method lookups go through the

__getattribute__() method. In this case, the __getattribute__() method raises an AttributeError

exception, so the method lookup fails, so the method call fails.

18.5. CLASSES THAT ACT LIKE FUNCTIONS

You can make an instance of a class callable — exactly like a function is callable — by defining the

__call__() method.

Notes You Want…

So You Write…

And Python Calls…

to “call” an instance like a

my_instance()

my_instance.__call__()

function

The zipfile module uses this to define a class that can decrypt an encrypted zip file with a given password.

The zip decryption algorithm requires you to store state during decryption. Defining the decryptor as a class

allows you to maintain this state within a single instance of the decryptor class. The state is initialized in the

__init__() method and updated as the file is decrypted. But since the class is also “callable” like a function,

you can pass the instance as the first argument of the map() function, like so:

477

# excerpt from zipfile.py

class _ZipDecrypter:

.

.

.

def __init__(self, pwd):

self.key0 = 305419896

self.key1 = 591751049

self.key2 = 878082192

for p in pwd:

self._UpdateKeys(p)

def __call__(self, c):

assert isinstance(c, int)

k = self.key2 | 2

c = c ^ (((k * (k^1)) >> 8) & 255)

self._UpdateKeys(c)

return c

.

.

.

zd = _ZipDecrypter(pwd)

bytes = zef_file.read(12)

h = list(map(zd, bytes[0:12]))

1. The _ZipDecryptor class maintains state in the form of three rotating keys, which are later updated in the

_UpdateKeys() method (not shown here).

2. The class defines a __call__() method, which makes class instances callable like functions. In this case, the

__call__() method decrypts a single byte of the zip file, then updates the rotating keys based on the byte

that was decrypted.

3. zd is an instance of the _ZipDecryptor class. The pwd variable is passed to the __init__() method, where

it is stored and used to update the rotating keys for the first time.

478

4. Given the first 12 bytes of a zip file, decrypt them by mapping the bytes to zd, in effect “calling” zd 12

times, which invokes the __call__() method 12 times, which updates its internal state and returns a

resulting byte 12 times.

18.6. CLASSES THAT ACT LIKE SETS

If your class acts as a container for a set of values — that is, if it makes sense to ask whether your class

“contains” a value — then it should probably define the following special methods that make it act like a set.

Notes You Want…

So You Write…

And Python

Calls…

the number of items

len(s)

s.__len__()

to know whether it contains a

x in s

s.__contains__(x)

specific value

The cgi module uses these methods in its FieldStorage class, which represents all of the form fields or query parameters submitted to a dynamic web page.

479

# A script which responds to http://example.com/search?q=cgi

import cgi

fs = cgi.FieldStorage()

if 'q' in fs:

do_search()

# An excerpt from cgi.py that explains how that works

class FieldStorage:

.

.

.

def __contains__(self, key):

if self.list is None:

raise TypeError('not indexable')

return any(item.name == key for item in self.list)

def __len__(self):

return len(self.keys())

1. Once you create an instance of the cgi.FieldStorage class, you can use the “in” operator to check

whether a particular parameter was included in the query string.

2. The __contains__() method is the magic that makes this work.

3. When you say if 'q' in fs, Python looks for the __contains__() method on the fs object, which is

defined in cgi.py. The value 'q' is passed into the __contains__() method as the key argument.

4. The same FieldStorage class also supports returning its length, so you can say len(fs) and it will call the

__len__() method on the FieldStorage class to return the number of query parameters that it identified.

5. The self.keys() method checks whether self.list is None, so the __len__ method doesn’t need to

duplicate this error checking.

18.7. CLASSES THAT ACT LIKE DICTIONARIES

Extending the previous section a bit, you can define classes that not only respond to the “in” operator and

the len() function, but they act like full-blown dictionaries, returning values based on keys.

480

Notes You Want…

So You Write…

And Python Calls…

to get a value by its key

x[key]

x.__getitem__(key)

to set a value by its key

x[key] = value

x.__setitem__(key, value)

to delete a key-value pair

del x[key]

x.__delitem__(key)

to provide a default value

x[nonexistent_key]

x.__missing__(nonexistent_key)

for missing keys

The FieldStorage class from the cgi module also defines these special methods, which means you can do things like this:

# A script which responds to http://example.com/search?q=cgi

import cgi

fs = cgi.FieldStorage()

if 'q' in fs:

do_search(fs['q'])

# An excerpt from cgi.py that shows how it works

class FieldStorage:

.

.

.

def __getitem__(self, key):

if self.list is None:

raise TypeError('not indexable')

found = []

for item in self.list:

if item.name == key: found.append(item)

if not found:

raise KeyError(key)

if len(found) == 1:

return found[0]

else:

return found

481

1. The fs object is an instance of cgi.FieldStorage, but you can still evaluate expressions like fs['q'].

2. fs['q'] invokes the __getitem__() method with the key parameter set to 'q'. It then looks up in its

internally maintained list of query parameters (self.list) for an item whose .name matches the given key.

18.8. CLASSES THAT ACT LIKE NUMBERS

Using the appropriate special methods, you can define your own classes that act like numbers. That is, you

can add them, subtract them, and perform other mathematical operations on them. This is how fractions are

implemented — the Fraction class implements these special methods, then you can do things like this:

>>> from fractions import Fraction

>>> x = Fraction(1, 3)

>>> x / 3

Fraction(1, 9)

Here is the comprehensive list of special methods you need to implement a number-like class.

Notes You Want…

So You Write…

And Python

Calls…

addition

x + y

x.__add__(y)

subtraction

x - y

x.__sub__(y)

multiplication

x * y

x.__mul__(y)

division

x / y

x.__truediv__(y)

floor division

x // y

x.__floordiv__(y)

modulo (remainder)

x % y

x.__mod__(y)

floor division & modulo

divmod(x, y)

x.__divmod__(y)

raise to power

x ** y

x.__pow__(y)

left bit-shift

x << y

x.__lshift__(y)

right bit-shift

x >> y

x.__rshift__(y)

bitwise and

x & y

x.__and__(y)

bitwise xor

x ^ y

x.__xor__(y)

bitwise or

x | y

x.__or__(y)

482

That’s all well and good if x is an instance of a class that implements those methods. But what if it doesn’t

implement one of them? Or worse, what if it implements it, but it can’t handle certain kinds of arguments?

For example:

>>> from fractions import Fraction

>>> x = Fraction(1, 3)

>>> 1 / x

Fraction(3, 1)

This is not a case of taking a Fraction and dividing it by an integer (as in the previous example). That case

was straightforward: x / 3 calls x.__truediv__(3), and the __truediv__() method of the Fraction class

handles all the math. But integers don’t “know” how to do arithmetic operations with fractions. So why does

this example work?

There is a second set of arithmetic special methods with reflected operands. Given an arithmetic operation

that takes two operands ( e.g. x / y), there are two ways to go about it:

1. Tell x to divide itself by y, or

2. Tell y to divide itself into x

The set of special methods above take the first approach: given x / y, they provide a way for x to say “I

know how to divide myself by y.” The following set of special methods tackle the second approach: they

provide a way for y to say “I know how to be the denominator and divide myself into x.”

Notes You Want…

So You Write…

And Python

Calls…

addition

x + y

y.__radd__(x)

subtraction

x - y

y.__rsub__(x)

multiplication

x * y

y.__rmul__(x)

division

x / y

y.__rtruediv__(x)

floor division

x // y

y.__rfloordiv__(x)

modulo (remainder)

x % y

y.__rmod__(x)

floor division & modulo

divmod(x, y)

y.__rdivmod__(x)

raise to power

x ** y

y.__rpow__(x)

483

left bit-shift

x << y

y.__rlshift__(x)

right bit-shift

x >> y

y.__rrshift__(x)

bitwise and

x & y

y.__rand__(x)

bitwise xor

x ^ y

y.__rxor__(x)

bitwise or

x | y

y.__ror__(x)

But wait! There’s more! If you’re doing “in-place” operations, like x /= 3, there are even more special

methods you can define.

Notes You Want…

So You Write…

And Python

Calls…

in-place addition

x += y

x.__iadd__(y)

in-place subtraction

x -= y

x.__isub__(y)

in-place multiplication

x *= y

x.__imul__(y)

in-place division

x /= y

x.__itruediv__(y)

in-place floor division

x //= y

x.__ifloordiv__(y)

in-place modulo

x %= y

x.__imod__(y)

in-place raise to power

x **= y

x.__ipow__(y)

in-place left bit-shift

x <<= y

x.__ilshift__(y)

in-place right bit-shift

x >>= y

x.__irshift__(y)

in-place bitwise and

x &= y

x.__iand__(y)

in-place bitwise xor

x ^= y

x.__ixor__(y)

in-place bitwise or

x |= y

x.__ior__(y)

Note: for the most part, the in-place operation methods are not required. If you don’t define an in-place

method for a particular operation, Python will try the methods. For example, to execute the expression x

/= y, Python will:

1. Try calling x.__itruediv__(y). If this method is defined and returns a value other than NotImplemented,

we’re done.

2. Try calling x.__truediv__(y). If this method is defined and returns a value other than NotImplemented, the

old value of x is discarded and replaced with the return value, just as if you had done x = x / y instead.

3. Try calling y.__rtruediv__(x). If this method is defined and returns a value other than NotImplemented,

the old value of x is discarded and replaced with the return value.

484

So you only need to define in-place methods like the __itruediv__() method if you want to do some

special optimization for in-place operands. Otherwise Python will essentially reformulate the in-place operand

to use a regular operand + a variable assignment.

There are also a few “unary” mathematical operations you can perform on number-like objects by

themselves.

Notes You Want…

So You Write…

And Python Calls…

negative number

-x

x.__neg__()

positive number

+x

x.__pos__()

absolute value

abs(x)

x.__abs__()

inverse

~x

x.__invert__()

complex number

complex(x)

x.__complex__()

integer

int(x)

x.__int__()

floating point number

float(x)

x.__float__()

number rounded to nearest

round(x)

x.__round__()

integer

number rounded to nearest n

round(x, n)

x.__round__(n)

digits

smallest integer >= x

math.ceil(x)

x.__ceil__()

largest integer <= x

math.floor(x)

x.__floor__()

truncate x to nearest integer

math.trunc(x)

x.__trunc__()

toward 0

PEP

number as a list index

a_list[x]

a_list[x.__index__()]

357

18.9. CLASSES THAT CAN BE COMPARED

I broke this section out from the previous one because comparisons are not strictly the purview of numbers.

Many datatypes can be compared — strings, lists, even dictionaries. If you’re creating your own class and it

makes sense to compare your objects to other objects, you can use the following special methods to

implement comparisons.

485

Notes You Want…

So You Write…

And Python

Calls…

equality

x == y

x.__eq__(y)

inequality

x != y

x.__ne__(y)

less than

x < y

x.__lt__(y)

less than or equal to

x <= y

x.__le__(y)

greater than

x > y

x.__gt__(y)

greater than or equal to

x >= y

x.__ge__(y)

truth value in a boolean context

if x:

x.__bool__()

☞ If you define a __lt__() method but no __gt__() method, Python will use the

__lt__() method with operands swapped. However, Python will not combine

methods. For example, if you define a __lt__() method and a __eq__() method and

try to test whether x <= y, Python will not call __lt__() and __eq__() in

sequence. It will only call the __le__() method.

18.10. CLASSES THAT CAN BE SERIALIZED

Python supports serializing and unserializing arbitrary objects. (Most Python references call this process

“pickling” and “unpickling.”) This can be useful for saving state to a file and restoring it later. All of the

native datatypes support pickling already. If you create a custom class that you want to be able to pickle, read up on the pickle protocol to see when and how the following special methods are called.

Notes You Want…

So You Write…

And Python Calls…

a custom object copy

copy.copy(x)

x.__copy__()

a custom object deepcopy

copy.deepcopy(x)

x.__deepcopy__()

to get an object’s state

pickle.dump(x, file)

x.__getstate__()

before pickling

to serialize an object

pickle.dump(x, file)

x.__reduce__()

to serialize an object (new pickle.dump(x, file,

x.__reduce_ex__(protocol_version)

pickling protocol)

protocol_version)

486

*

control over how an

x = pickle.load(file)

x.__getnewargs__()

object is created during

unpickling

*

to restore an object’s

x = pickle.load(file)

x.__setstate__()

state after unpickling

* To recreate a serialized object, Python needs to create a new object that looks like the serialized object,

then set the values of all the attributes on the new object. The __getnewargs__() method controls how

the object is created, then the __setstate__() method controls how the attribute values are restored.

18.11. CLASSES THAT CAN BE USED IN A with BLOCK

A with block defines a runtime context; you “enter” the context when you execute the with statement, and you “exit” the context after you execute the last statement in the block.

Notes You Want…

So You Write…

And Python Calls…

do something special when

with x:

x.__enter__()

entering a with block

do something special when leaving

with x:

x.__exit__(exc_type,

a with block

exc_value,

traceback)

This is how the with file idiom works.

487

# excerpt from io.py:

def _checkClosed(self, msg=None):

'''Internal: raise an ValueError if file is closed

'''

if self.closed:

raise ValueError('I/O operation on closed file.'

if msg is None else msg)

def __enter__(self):

'''Context management protocol. Returns self.'''

self._checkClosed()

return self

def __exit__(self, *args):

'''Context management protocol. Calls close()'''

self.close()

1. The file object defines both an __enter__() and an __exit__() method. The __enter__() method checks

that the file is open; if it’s not, the _checkClosed() method raises an exception.

2. The __enter__() method should almost always return self — this is the object that the with block will

use to dispatch properties and methods.

3. After the with block, the file object automatically closes. How? In the __exit__() method, it calls

self.close().

☞ The __exit__() method will always be called, even if an exception is raised inside

the with block. In fact, if an exception is raised, the exception information will be

passed to the __exit__() method. See With Statement Context Managers for more details.

For more on context managers, see Closing Files Automatically and Redirecting Standard Output.

488

18.12. REALLY ESOTERIC STUFF

If you know what you’re doing, you can gain almost complete control over how classes are compared, how

attributes are defined, and what kinds of classes are considered subclasses of your class.

Notes You Want…

So You Write…

And Python Calls…

a class constructor

x = MyClass()

x.__new__()

*

a class destructor

del x

x.__del__()

only a specific set of

x.__slots__()

attributes to be defined

a custom hash value

hash(x)

x.__hash__()

to get a property’s value

x.color

type(x).__dict__['color'].__get__(x,

type(x))

to set a property’s value

x.color =

type(x).__dict__['color'].__set__(x,

'PapayaWhip'

'PapayaWhip')

to delete a property

del x.color

type(x).__dict__['color'].__del__(x)

to control whether an

isinstance(x,

MyClass.__instancecheck__(x)

object is an instance of

MyClass)

your class

to control whether a

issubclass(C,

MyClass.__subclasscheck__(C)

class is a subclass of

MyClass)

your class

to control whether a

issubclass(C, MyABC)

MyABC.__subclasshook__(C)

class is a subclass of

your abstract base class

* Exactly when Python calls the __del__() special method is incredibly complicated. To fully understand it, you need to know how Python keeps track of objects in memory. Here’s a good article on Python garbage

collection and class destructors. You should also read about weak references, the weakref module, and probably the gc module for good measure.

18.13. FURTHER READING

Modules mentioned in this appendix:

489

zipfile module

cgi module

collections module

math module

pickle module

copy module

abc (“Abstract Base Classes”) module

Other light reading:

Format Specification Mini-Language

Python data model

Built-in types

PEP 357: Allowing Any Object to be Used for Slicing

PEP 3119: Introducing Abstract Base Classes

490

CHAPTER 19. WHERE TO GO FROM HERE

Go forth on your path, as it exists only through your walking.

— St. Augustine of Hippo (attributed)

19.1. THINGS TO READ

Unfortunately,IcannotwritecovereveryfacetofPython3inthisbook.Fortunately,therearemany

wonderful, freely available tutorials available elsewhere.

Decorators:

Function Decorators by Ariel Ortiz

More on Function Decorators by Ariel Ortiz

Charming Python: Decorators make magic easy by David Mertz

Function Definitions in the official Python documentation Properties:

The Python property builtin by Adam Gomaa

Getters/Setters/Fuxors by Ryan Tomayko

property() function in the official Python documentation Descriptors:

How-To Guide For Descriptors by Raymond Hettinger

Charming Python: Python elegance and warts, Part 2 by David Mertz

Python Descriptors by Mark Summerfield

Invoking Descriptors in the official Python documentation 491

Threading & multiprocessing:

threading module

threading — Manage concurrent threads

multiprocessing module

multiprocessing — Manage processes like threads

Python threads and the Global Interpreter Lock by Jesse Noller

Inside the Python GIL (video) by David Beazley

Metaclasses:

Metaclass programming in Python by David Mertz and Michele Simionato

Metaclass programming in Python, Part 2 by David Mertz and Michele Simionato

Metaclass programming in Python, Part 3 by David Mertz and Michele Simionato In addition, Doug Hellman’s Python Module of the Week is a fantastic guide to many of the modules in the Python standard library.

19.2. WHERE TO LOOK FOR PYTHON 3-COMPATIBLE CODE

As Python 3 is relatively new, there is a dearth of compatible libraries. Here are some of the places to look

for code that works with Python 3.

Python Package Index: list of Python 3 packages

Python Cookbook: list of recipes tagged “python3”

Google Project Hosting: list of projects tagged “python3”

SourceForge: list of projects matching “Python 3”

GitHub: list of projects matching “python3” (also, list of projects matching “python 3” )

BitBucket: list of projects matching “python3” (and those matching “python 3”)

492

CHAPTER 20. TROUBLESHOOTING

Where’s the ANY key?

variously attributed

20.1. DIVING IN

FIXME

20.2. GETTING TO THE COMMAND LINE

Throughout this book, there are examples of executing Python programs from the command line. Where is

the command line?

On Linux, look in your Applications menu for a program called Terminal. (It may be in a submenu like

Accessories or System.)

On Mac OS X, there is an application called Terminal in your /Applications/Utilities/ folder. To get

there, click on your desktop, open the Go menu, select Go to folder..., and type /Applications/

Utilities/. Then double-click the Terminal program.

On Windows, click Start, select Run..., type cmd, and press ENTER.

20.3. RUNNING PYTHON ON THE COMMAND LINE

Once you get to the command line, you should be able to run the Python interactive shell. On the Linux or Mac OS X command line, type python3 and press ENTER. On the Windows command line, type

c:\python31\python and press ENTER. If all goes well, you should see something like this:

493

you@localhost:~$ python3

Python 3.1 (r31:73572, Jul 28 2009, 06:52:23)

[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>>

(Type exit() and press ENTER to exit the Python interactive shell and go back to the command line. This

works on all platforms.)

If you get a “command not found” error, it probably means you don’t have Python 3 installed.

you@localhost:~$ python3

bash: python3: command not found

On the other hand, if you get into a Python interactive shell but the version number is not what you

expected, you may have more than one version of Python installed. This happens most often on Linux and

Mac OS X systems, where an older version of Python is pre-installed. You can install the latest version

without deleting the older version (they will live side-by-side in peace), but you will need to be more specific

when you run Python from the command line.

For example, on my home Linux box, I have several versions of Python installed so I can test the Python

software that I write. To run a specific version, I can type python3.0, python3.1, or python2.6.

494

mark@atlantis:~$ python3.0

Python 3.0.1+ (r301:69556, Apr 15 2009, 17:25:52)

[GCC 4.3.3] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> exit()

mark@atlantis:~$ python3.1

Python 3.1 (r31:73572, Jul 28 2009, 06:52:23)

[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> exit()

mark@atlantis:~$ python2.6

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)

[GCC 4.4.3] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> exit()

© 2001–9 Mark Pilgrim

495