Python 2.6 有什麼新功能¶
- 作者:
A.M. Kuchling (amk at amk.ca)
本文介紹了已於 2008 年 10 月 1 日發布的 Python 2.6 有哪些新功能。發布時間表請見 PEP 361。
The major theme of Python 2.6 is preparing the migration path to
Python 3.0, a major redesign of the language. Whenever possible,
Python 2.6 incorporates new features and syntax from 3.0 while
remaining compatible with existing code by not removing older features
or syntax. When it's not possible to do that, Python 2.6 tries to do
what it can, adding compatibility functions in a
future_builtins module and a -3 switch to warn about
usages that will become unsupported in 3.0.
Some significant new packages have been added to the standard library,
such as the multiprocessing and json modules, but
there aren't many new features that aren't related to Python 3.0 in
some way.
Python 2.6 also sees a number of improvements and bugfixes throughout the source. A search through the change logs finds there were 259 patches applied and 612 bugs fixed between Python 2.5 and 2.6. Both figures are likely to be underestimates.
This article doesn't attempt to provide a complete specification of the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.6. If you want to understand the rationale for the design and implementation, refer to the PEP for a particular new feature. Whenever possible, "What's New in Python" links to the bug/patch item for each change.
Python 3.0¶
The development cycle for Python versions 2.6 and 3.0 was synchronized, with the alpha and beta releases for both versions being made on the same days. The development of 3.0 has influenced many features in 2.6.
Python 3.0 is a far-ranging redesign of Python that breaks compatibility with the 2.x series. This means that existing Python code will need some conversion in order to run on Python 3.0. However, not all the changes in 3.0 necessarily break compatibility. In cases where new features won't cause existing code to break, they've been backported to 2.6 and are described in this document in the appropriate place. Some of the 3.0-derived features are:
A
__complex__()method for converting objects to a complex number.Alternate syntax for catching exceptions:
except TypeError as exc.The addition of
functools.reduce()as a synonym for the built-inreduce()function.
Python 3.0 adds several new built-in functions and changes the
semantics of some existing builtins. Functions that are new in 3.0
such as bin() have simply been added to Python 2.6, but existing
builtins haven't been changed; instead, the future_builtins
module has versions with the new 3.0 semantics. Code written to be
compatible with 3.0 can do from future_builtins import hex, map as
necessary.
A new command-line switch, -3, enables warnings
about features that will be removed in Python 3.0. You can run code
with this switch to see how much work will be necessary to port
code to 3.0. The value of this switch is available
to Python code as the boolean variable sys.py3kwarning,
and to C extension code as Py_Py3kWarningFlag.
Changes to the Development Process¶
While 2.6 was being developed, the Python development process underwent two significant changes: we switched from SourceForge's issue tracker to a customized Roundup installation, and the documentation was converted from LaTeX to reStructuredText.
New Issue Tracker: Roundup¶
For a long time, the Python developers had been growing increasingly annoyed by SourceForge's bug tracker. SourceForge's hosted solution doesn't permit much customization; for example, it wasn't possible to customize the life cycle of issues.
The infrastructure committee of the Python Software Foundation therefore posted a call for issue trackers, asking volunteers to set up different products and import some of the bugs and patches from SourceForge. Four different trackers were examined: Jira, Launchpad, Roundup, and Trac. The committee eventually settled on Jira and Roundup as the two candidates. Jira is a commercial product that offers no-cost hosted instances to free-software projects; Roundup is an open-source project that requires volunteers to administer it and a server to host it.
After posting a call for volunteers, a new Roundup installation was set up at https://bugs.python.org. One installation of Roundup can host multiple trackers, and this server now also hosts issue trackers for Jython and for the Python web site. It will surely find other uses in the future. Where possible, this edition of "What's New in Python" links to the bug/patch item for each change.
Hosting of the Python bug tracker is kindly provided by
Upfront Systems
of Stellenbosch, South Africa. Martin von Löwis put a
lot of effort into importing existing bugs and patches from
SourceForge; his scripts for this import operation are at
https://svn.python.org/view/tracker/importer/ and may be useful to
other projects wishing to move from SourceForge to Roundup.
也參考
- https://bugs.python.org
Python 問題追蹤系統。
- https://bugs.jython.org:
Jython 問題追蹤系統。
- https://roundup.sourceforge.io/
Roundup downloads and documentation.
- https://svn.python.org/view/tracker/importer/
Martin von Löwis 的轉換腳本。
新文件格式:使用 Sphinx 的 reStructuredText¶
The Python documentation was written using LaTeX since the project started around 1989. In the 1980s and early 1990s, most documentation was printed out for later study, not viewed online. LaTeX was widely used because it provided attractive printed output while remaining straightforward to write once the basic rules of the markup were learned.
Today LaTeX is still used for writing publications destined for printing, but the landscape for programming tools has shifted. We no longer print out reams of documentation; instead, we browse through it online and HTML has become the most important format to support. Unfortunately, converting LaTeX to HTML is fairly complicated and Fred L. Drake Jr., the long-time Python documentation editor, spent a lot of time maintaining the conversion process. Occasionally people would suggest converting the documentation into SGML and later XML, but performing a good conversion is a major task and no one ever committed the time required to finish the job.
During the 2.6 development cycle, Georg Brandl put a lot of effort into building a new toolchain for processing the documentation. The resulting package is called Sphinx, and is available from https://www.sphinx-doc.org/.
Sphinx concentrates on HTML output, producing attractively styled and modern HTML; printed output is still supported through conversion to LaTeX. The input format is reStructuredText, a markup syntax supporting custom extensions and directives that is commonly used in the Python community.
Sphinx is a standalone package that can be used for writing, and almost two dozen other projects (listed on the Sphinx web site) have adopted Sphinx as their documentation tool.
也參考
- Python 文件撰寫
說明如何為 Python 撰寫文件。
- Sphinx
Sphinx 工具鏈的文件和程式碼。
- Docutils
底層 reStructuredText 剖析器和工具集。
PEP 343:'with' 陳述式¶
The previous version, Python 2.5, added the 'with'
statement as an optional feature, to be enabled by a from __future__
import with_statement directive. In 2.6 the statement no longer needs to
be specially enabled; this means that with is now always a
keyword. The rest of this section is a copy of the corresponding
section from the "What's New in Python 2.5" document; if you're
familiar with the 'with' statement
from Python 2.5, you can skip this section.
The 'with' statement clarifies code that previously would use
try...finally blocks to ensure that clean-up code is executed. In this
section, I'll discuss the statement as it will commonly be used. In the next
section, I'll examine the implementation details and show how to write objects
for use with this statement.
The 'with' statement is a control-flow structure whose basic
structure is:
with expression [as variable]:
with-block
The expression is evaluated, and it should result in an object that supports the
context management protocol (that is, has __enter__() and __exit__()
methods).
The object's __enter__() is called before with-block is executed and
therefore can run set-up code. It also may return a value that is bound to the
name variable, if given. (Note carefully that variable is not assigned
the result of expression.)
After execution of the with-block is finished, the object's __exit__()
method is called, even if the block raised an exception, and can therefore run
clean-up code.
Some standard Python objects now support the context management protocol and can
be used with the 'with' statement. File objects are one example:
with open('/etc/passwd', 'r') as f:
for line in f:
print line
... 更多處理程式碼 ...
After this statement has executed, the file object in f will have been
automatically closed, even if the for loop raised an exception
part-way through the block.
備註
In this case, f is the same object created by open(), because
__enter__() returns self.
The threading module's locks and condition variables also support the
'with' statement:
lock = threading.Lock()
with lock:
# Critical section of code
...
The lock is acquired before the block is executed and always released once the block is complete.
The localcontext() function in the decimal module makes
it easy to save and restore the current decimal context, which encapsulates
the desired precision and rounding characteristics for computations:
from decimal import Decimal, Context, localcontext
# Displays with default precision of 28 digits
v = Decimal('578')
print v.sqrt()
with localcontext(Context(prec=16)):
# All code in this block uses a precision of 16 digits.
# The original context is restored on exiting the block.
print v.sqrt()
Writing Context Managers¶
Under the hood, the 'with' statement is fairly complicated. Most
people will only use 'with' in company with existing objects and
don't need to know these details, so you can skip the rest of this section if
you like. Authors of new objects will need to understand the details of the
underlying implementation and should keep reading.
A high-level explanation of the context management protocol is:
The expression is evaluated and should result in an object called a "context manager". The context manager must have
__enter__()and__exit__()methods.The context manager's
__enter__()method is called. The value returned is assigned to VAR. If noas VARclause is present, the value is simply discarded.BLOCK 中的程式碼會被執行。
If BLOCK raises an exception, the context manager's
__exit__()method is called with three arguments, the exception details (type, value, traceback, the same values returned bysys.exc_info(), which can also beNoneif no exception occurred). The method's return value controls whether an exception is re-raised: any false value re-raises the exception, andTruewill result in suppressing it. You'll only rarely want to suppress the exception, because if you do the author of the code containing the 'with' statement will never realize anything went wrong.If BLOCK didn't raise an exception, the
__exit__()method is still called, but type, value, and traceback are allNone.
Let's think through an example. I won't present detailed code but will only sketch the methods necessary for a database that supports transactions.
(For people unfamiliar with database terminology: a set of changes to the database are grouped into a transaction. Transactions can be either committed, meaning that all the changes are written into the database, or rolled back, meaning that the changes are all discarded and the database is unchanged. See any database textbook for more information.)
Let's assume there's an object representing a database connection. Our goal will be to let the user write code like this:
db_connection = DatabaseConnection()
with db_connection as cursor:
cursor.execute('insert into ...')
cursor.execute('delete from ...')
# ... 更多操作 ...
The transaction should be committed if the code in the block runs flawlessly or
rolled back if there's an exception. Here's the basic interface for
DatabaseConnection that I'll assume:
class DatabaseConnection:
# Database interface
def cursor(self):
"Returns a cursor object and starts a new transaction"
def commit(self):
"Commits current transaction"
def rollback(self):
"Rolls back current transaction"
The __enter__() method is pretty easy, having only to start a new
transaction. For this application the resulting cursor object would be a useful
result, so the method will return it. The user can then add as cursor to
their 'with' statement to bind the cursor to a variable name.
class DatabaseConnection:
...
def __enter__(self):
# Code to start a new transaction
cursor = self.cursor()
return cursor