2565
Comment:
|
6494
added Fabio Zadrozny's tips
|
Deletions are marked like this. | Additions are marked like this. |
Line 4: | Line 4: |
in five five years from now... See http://www.python.org/peps/pep-3000.html for more |
five years from now. See [[http://www.python.org/peps/pep-3000.html|PEP 3000]] for more |
Line 7: | Line 7: |
* Keep in mind that only a little subset of existing Python 2.6 code is valid on Python 3.0. There is no guarantee that your code will run unmodified on Python 3.0, even if you follow the advices listed here. * See also the [[http://svn.python.org/view/sandbox/trunk/2to3/README?view=markup|2to3]] tool, that helps translating Python 2.6 to Python 3.0 code. Some changes listed here can be automatically translated with this tool. Also, check the changes that '''can't''' be translated by the tool. = Unit Tests = Automated testing is generally better than debugging, and is your safety-net for any kind of refactoring, not only when migrating to a newer Python. Use PyUnit (unittest), DocTest or any alternative (see UnitTests) to help you. '''Write unit tests for all new or refactored code.''' |
|
Line 11: | Line 21: |
two integers are divided, e.g. 3/2 => 1. While correct if we assume that dividing integers means integer division (the remainder is accessible through the modulo operator %) it's |
two integers are divided (e.g., {{{3/2}}} yields {{{1}}}). While this is correct if we assume that dividing integers means integer division, it's |
Line 15: | Line 24: |
a future Python version, so that a/b with yield a float as a result regardless of the types of the numbers a and b, and a new floor division operator // will perform integer division. See See http://www.python.org/peps/pep-0238.html |
a future Python version, so that {{{a/b}}} will yield a float as a result even if both {{{a}}} and {{{b}}} are integers, and a new floor division operator {{{//}}} will perform integer division. See See [[http://www.python.org/peps/pep-0238.html|PEP 238]] for more information. |
Line 20: | Line 29: |
'''Use true and floor division in new code''' | '''Use true and floor division in new code.''' You can enable the new behaviour in Python 2.x as follows: |
Line 23: | Line 34: |
from __future__ import division # Enable the new behaviour f = 3/2 # 1.5 i = 3//2 # 1 |
>>> from __future__ import division # Enable the new behaviour >>> 3/2 1.5 >>> 3//2 1 |
Line 30: | Line 41: |
= Absolute imports = In Python 2.x, imports are implicitly relative. For instance, if you're editing the file {{{foo/__init__.py}}} and want to import the module at {{{foo/bar.py}}}, you could use {{{import bar}}}. In Python 3.0, this won't work, as all imports will be absolute by default. You should instead use {{{from foo import bar}}}; if you want to import a specific function or variable from {{{bar}}}, you can use relative imports, such as {{{from .bar import myfunction}}}). See [[http://www.python.org/dev/peps/pep-0328/|PEP 328]] for more information. '''Don't use implicitly relative imports in new code.''' |
|
Line 35: | Line 53: |
will go away in some future version, and while most code will still work when the default swaps from old style to new style, there are |
will go away in Python 3.0, and while most code will still work when the default switches from old style to new style, there are |
Line 38: | Line 56: |
extra features. See http://www.python.org/doc/newstyle.html | extra features. See [[http://www.python.org/doc/newstyle/|New-style Classes]] for more information. |
Line 40: | Line 58: |
'''Use new style classes in new code''' | '''Use new style classes in new code.''' |
Line 42: | Line 60: |
Don't write | * Don't write |
Line 48: | Line 66: |
Write | * Instead, write |
Line 55: | Line 73: |
= Let all exception classes inherit from Exception = | = Exception class inheritance = |
Line 57: | Line 75: |
From Python 3.0, all exceptions must be derived from Base''''''Exception, | Starting from Python 3.0, all exceptions must be derived from Base''''''Exception, |
Line 59: | Line 77: |
Exception from Python 2.5. See http://www.python.org/peps/pep-0352.html | Exception from Python 2.5. See [[http://www.python.org/peps/pep-0352.html|PEP 352]] for more information. |
Line 61: | Line 79: |
'''When defining new exception classes, always inherit (directly or indirectly) from Exception''' |
'''When defining new exception classes, always inherit (directly or indirectly) from {{{Exception}}}.''' |
Line 65: | Line 82: |
class MyException(Excption): pass | class MyException(Exception): pass |
Line 68: | Line 85: |
= Use parenthesis for Exception argument = | = Arguments for raise statement = |
Line 70: | Line 87: |
The syntax | The {{{raise}}} statement currently accepts different syntaxes. This will be consolidated so that only one argument is allowed for {{{raise}}}: the exception object, created like any other object. Other syntaxes will be deprecated. '''Write the {{{raise}}} statement with the exception object as the only argument.''' * Don't write: |
Line 72: | Line 93: |
raise MyException "A nasty error" | raise MyException, "A nasty error" raise "Foo bar error: Invalid value" |
Line 74: | Line 96: |
will be deprecated. Use | * Instead, write: |
Line 77: | Line 100: |
raise FooBarError("Invalid value") | |
Line 78: | Line 102: |
instead. | |
Line 80: | Line 103: |
= Don't compare uncomparable objects = | = Comparison of incompatible types = |
Line 82: | Line 105: |
In the future, x < y and friends (>, <=, >=) will raise an exception instead of an arbitrary result, if type(x) != type(y) unless the types explicitly define the behaviour for these comparisions. |
In the future, {{{x < y}}} and friends ({{{>}}}, {{{<=}}}, {{{>=}}}) will raise an exception instead of an arbitrary result, if {{{type(x) != type(y)}}} unless the types explicitly define the behaviour for these comparisions. |
Line 86: | Line 107: |
= Don't use <> = | '''Don't compare objects of different types with undefined comparison behaviour.''' |
Line 88: | Line 109: |
It's enough with one inequality operator. Almost everybody uses !=. <> will go away. | = Deprecation of little-used alternative operators = One obvious way to test for inequality already exists: the {{{!=}}} operator. The rarely-used {{{<>}}} will go away. '''Use only {{{!=}}} for inequality comparison.''' The backtick syntax {{{`foo`}}}, which is equivalent to {{{repr(foo)}}}, will not exist in Python 3.0. Almost all code currently uses {{{repr(foo)}}} for this purpose, and the backtick syntax is little-known and less readable. '''Use only {{{repr(foo)}}} for the representation of an object.''' = New keywords = All of the names {{{with}}}, {{{as}}}, {{{nonlocal}}}, {{{True}}} and {{{False}}} are becoming keywords. Code that attempts to assign to those names will generate an exception in Python 3.0. '''Don't assign to names that will become keywords.''' = See more = Here are some more tips on writing Python code to be future proof with Python 3.0. * Collin Winter has some tips in: [[http://oakwinter.com/code/porting-setuptools-to-py3k/]] * Fabio Zadrozny gives some tips for those interested in writing code that runs on Python 2 and Python 3 in: [[http://pydev.blogspot.com/2008/11/making-code-work-in-python-2-and-3.html]] = More changes in the future? = The following little code might be useful to run when you upgrade to a new Python version. It shows how some new features in Python are gradually becoming enabled. (This example is from Python 2.3.) {{{ >>> import __future__ >>> for x in __future__.all_feature_names: ... print x, getattr(__future__, x) ... nested_scopes _Feature((2, 1, 0, 'beta', 1), (2, 2, 0, 'alpha', 0), 16) generators _Feature((2, 2, 0, 'alpha', 1), (2, 3, 0, 'final', 0), 4096) division _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192) }}} The second tuple (e.g. (3, 0, 0, 'alpha', 0) for division) shows when a new feature will become the default. ---- CategoryDocumentation |
Python is a mature language, but it hasn't stopped evolving, and there are some issues to consider when coding Python, if you want your code to work with the latest version of Python five years from now. See PEP 3000 for more information.
- Keep in mind that only a little subset of existing Python 2.6 code is valid on Python 3.0. There is no guarantee that your code will run unmodified on Python 3.0, even if you follow the advices listed here.
See also the 2to3 tool, that helps translating Python 2.6 to Python 3.0 code. Some changes listed here can be automatically translated with this tool. Also, check the changes that can't be translated by the tool.
Unit Tests
Automated testing is generally better than debugging, and is your safety-net for any kind of refactoring, not only when migrating to a newer Python. Use PyUnit (unittest), DocTest or any alternative (see UnitTests) to help you.
Write unit tests for all new or refactored code.
True Division
Since the beginning, Python has yielded an integer result when two integers are divided (e.g., 3/2 yields 1). While this is correct if we assume that dividing integers means integer division, it's not always obvious to beginners. This behaviour will change in a future Python version, so that a/b will yield a float as a result even if both a and b are integers, and a new floor division operator // will perform integer division. See See PEP 238 for more information.
Use true and floor division in new code.
You can enable the new behaviour in Python 2.x as follows:
>>> from __future__ import division # Enable the new behaviour >>> 3/2 1.5 >>> 3//2 1
Absolute imports
In Python 2.x, imports are implicitly relative. For instance, if you're editing the file foo/__init__.py and want to import the module at foo/bar.py, you could use import bar.
In Python 3.0, this won't work, as all imports will be absolute by default. You should instead use from foo import bar; if you want to import a specific function or variable from bar, you can use relative imports, such as from .bar import myfunction). See PEP 328 for more information.
Don't use implicitly relative imports in new code.
New style classes
Currently, there are two kinds of classes in Python. The 'classic' or old style classes, and the new style classes. Old style classes will go away in Python 3.0, and while most code will still work when the default switches from old style to new style, there are some differences in semantics, and the new style classes have some extra features. See New-style Classes for more information.
Use new style classes in new code.
- Don't write
class X: pass
- Instead, write
class X(object): pass
Exception class inheritance
Starting from Python 3.0, all exceptions must be derived from BaseException, which will be the base class for KeyboardInterrupt, SystemExit and Exception from Python 2.5. See PEP 352 for more information.
When defining new exception classes, always inherit (directly or indirectly) from Exception.
class MyException(Exception): pass
Arguments for raise statement
The raise statement currently accepts different syntaxes. This will be consolidated so that only one argument is allowed for raise: the exception object, created like any other object. Other syntaxes will be deprecated.
Write the raise statement with the exception object as the only argument.
- Don't write:
raise MyException, "A nasty error" raise "Foo bar error: Invalid value"
- Instead, write:
raise MyException("A nasty error") raise FooBarError("Invalid value")
Comparison of incompatible types
In the future, x < y and friends (>, <=, >=) will raise an exception instead of an arbitrary result, if type(x) != type(y) unless the types explicitly define the behaviour for these comparisions.
Don't compare objects of different types with undefined comparison behaviour.
Deprecation of little-used alternative operators
One obvious way to test for inequality already exists: the != operator. The rarely-used <> will go away.
Use only != for inequality comparison.
The backtick syntax `foo`, which is equivalent to repr(foo), will not exist in Python 3.0. Almost all code currently uses repr(foo) for this purpose, and the backtick syntax is little-known and less readable.
Use only repr(foo) for the representation of an object.
New keywords
All of the names with, as, nonlocal, True and False are becoming keywords. Code that attempts to assign to those names will generate an exception in Python 3.0.
Don't assign to names that will become keywords.
See more
Here are some more tips on writing Python code to be future proof with Python 3.0.
Collin Winter has some tips in: http://oakwinter.com/code/porting-setuptools-to-py3k/
Fabio Zadrozny gives some tips for those interested in writing code that runs on Python 2 and Python 3 in: http://pydev.blogspot.com/2008/11/making-code-work-in-python-2-and-3.html
More changes in the future?
The following little code might be useful to run when you upgrade to a new Python version. It shows how some new features in Python are gradually becoming enabled. (This example is from Python 2.3.)
>>> import __future__ >>> for x in __future__.all_feature_names: ... print x, getattr(__future__, x) ... nested_scopes _Feature((2, 1, 0, 'beta', 1), (2, 2, 0, 'alpha', 0), 16) generators _Feature((2, 2, 0, 'alpha', 1), (2, 3, 0, 'final', 0), 4096) division _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
The second tuple (e.g. (3, 0, 0, 'alpha', 0) for division) shows when a new feature will become the default.