创新互联Python教程:Python2.4有什么新变化

python 2.4 有什么新变化

作者

在黄冈等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站制作、网站建设 网站设计制作按需规划网站,公司网站建设,企业网站建设,高端网站设计,网络营销推广,外贸网站制作,黄冈网站建设费用合理。

A.M. Kuchling

本文介绍了2005年3月30日发布的 Python 2.4.1 的新功能。

Python 2.4 is a medium-sized release. It doesn’t introduce as many changes as the radical Python 2.2, but introduces more features than the conservative 2.3 release. The most significant new language features are function decorators and generator expressions; most other changes are to the standard library.

According to the CVS change logs, there were 481 patches applied and 502 bugs fixed between Python 2.3 and 2.4. Both figures are likely to be underestimates.

This article doesn’t attempt to provide a complete specification of every single new feature, but instead provides a brief introduction to each feature. For full details, you should refer to the documentation for Python 2.4, such as the Python Library Reference and the Python Reference Manual. Often you will be referred to the PEP for a particular new feature for explanations of the implementation and design rationale.

PEP 218: 内置集合对象

Python 2.3 introduced the sets module. C implementations of set data types have now been added to the Python core as two new built-in types, set(iterable) and frozenset(iterable). They provide high speed operations for membership testing, for eliminating duplicates from sequences, and for mathematical operations like unions, intersections, differences, and symmetric differences.

 
 
 
 
  1. >>> a = set('abracadabra') # form a set from a string
  2. >>> 'z' in a # fast membership testing
  3. False
  4. >>> a # unique letters in a
  5. set(['a', 'r', 'b', 'c', 'd'])
  6. >>> ''.join(a) # convert back into a string
  7. 'arbcd'
  8. >>> b = set('alacazam') # form a second set
  9. >>> a - b # letters in a but not in b
  10. set(['r', 'd', 'b'])
  11. >>> a | b # letters in either a or b
  12. set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
  13. >>> a & b # letters in both a and b
  14. set(['a', 'c'])
  15. >>> a ^ b # letters in a or b but not both
  16. set(['r', 'd', 'b', 'm', 'z', 'l'])
  17. >>> a.add('z') # add a new element
  18. >>> a.update('wxy') # add multiple new elements
  19. >>> a
  20. set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
  21. >>> a.remove('x') # take one element out
  22. >>> a
  23. set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])

The frozenset() type is an immutable version of set(). Since it is immutable and hashable, it may be used as a dictionary key or as a member of another set.

The sets module remains in the standard library, and may be useful if you wish to subclass the Set or ImmutableSet classes. There are currently no plans to deprecate the module.

参见

PEP 218 - 添加内置Set对象类型

最初由 Greg Wilson 提出,由 Raymond Hettinger 最终实现。

PEP 237: 统一长整数和整数

The lengthy transition process for this PEP, begun in Python 2.2, takes another step forward in Python 2.4. In 2.3, certain integer operations that would behave differently after int/long unification triggered FutureWarning warnings and returned values limited to 32 or 64 bits (depending on your platform). In 2.4, these expressions no longer produce a warning and instead produce a different result that’s usually a long integer.

The problematic expressions are primarily left shifts and lengthy hexadecimal and octal constants. For example, 2 << 32 results in a warning in 2.3, evaluating to 0 on 32-bit platforms. In Python 2.4, this expression now returns the correct answer, 8589934592.

参见

PEP 237 - 统一长整数和整数

原始PEP由 Moshe Zadka 和 GvR 撰写,2.4 的变更由 Kalle Svensson 实现。

PEP 289: 生成器表达式

The iterator feature introduced in Python 2.2 and the itertools module make it easier to write programs that loop through large data sets without having the entire data set in memory at one time. List comprehensions don’t fit into this picture very well because they produce a Python list object containing all of the items. This unavoidably pulls all of the objects into memory, which can be a problem if your data set is very large. When trying to write a functionally styled program, it would be natural to write something like:

 
 
 
 
  1. links = [link for link in get_all_links() if not link.followed]
  2. for link in links:
  3. ...

代替:

 
 
 
 
  1. for link in get_all_links():
  2. if link.followed:
  3. continue
  4. ...

The first form is more concise and perhaps more readable, but if you’re dealing with a large number of link objects you’d have to write the second form to avoid having all link objects in memory at the same time.

Generator expressions work similarly to list comprehensions but don’t materialize the entire list; instead they create a generator that will return elements one by one. The above example could be written as:

 
 
 
 
  1. links = (link for link in get_all_links() if not link.followed)
  2. for link in links:
  3. ...

Generator expressions always have to be written inside parentheses, as in the above example. The parentheses signalling a function call also count, so if you want to create an iterator that will be immediately passed to a function you could write:

 
 
 
 
  1. print sum(obj.count for obj in list_all_objects())

Generator expressions differ from list comprehensions in various small ways. Most notably, the loop variable (obj in the above example) is not accessible outside of the generator expression. List comprehensions leave the variable assigned to its last value; future versions of Python will change this, making list comprehensions match generator expressions in this respect.

参见

PEP 289 - 生成器表达式

Proposed by Raymond Hettinger and implemented by Jiwon Seo with early efforts steered by Hye-Shik Chang.

PEP 292: 更简单的字符串替换

Some new classes in the standard library provide an alternative mechanism for substituting variables into strings; this style of substitution may be better for applications where untrained users need to edit templates.

按名称替换变量的常用方式是 % 运算符:

 
 
 
 
  1. >>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
  2. '2: The Best of Times'

When writing the template string, it can be easy to forget the i or s after the closing parenthesis. This isn’t a big problem if the template is in a Python module, because you run the code, get an “Unsupported format character” ValueError, and fix the problem. However, consider an application such as Mailman where template strings or translations are being edited by users who aren’t aware of the Python language. The format string’s syntax is complicated to explain to such users, and if they make a mistake, it’s difficult to provide helpful feedback to them.

PEP 292 adds a Template class to the string module that uses $ to indicate a substitution:

 
 
 
 
  1. >>> import string
  2. >>> t = string.Template('$page: $title')
  3. >>> t.substitute({'page':2, 'title': 'The Best of Times'})
  4. '2: The Best of Times'

If a key is missing from the dictionary, the substitute() method will raise a KeyError. There’s also a safe_substitute() method that ignores missing keys:

 
 
 
 
  1. >>> t = string.Template('$page: $title')
  2. >>> t.safe_substitute({'page':3})
  3. '3: $title'

参见

PEP 292 - 更简单的字符串替换

由 Barry Warsaw 撰写并实现

PEP 318: 函数和方法的装饰器

Python 2.2 extended Python’s object model by adding static methods and class methods, but it didn’t extend Python’s syntax to provide any new way of defining static or class methods. Instead, you had to write a def statement in the usual way, and pass the resulting method to a staticmethod() or classmethod() function that would wrap up the function as a method of the new type. Your code would look like this:

 
 
 
 
  1. class C:
  2. def meth (cls):
  3. ...
  4. meth = classmethod(meth) # Rebind name to wrapped-up class method

If the method was very long, it would be easy to miss or forget the classmethod() invocation after the function body.

The intention was always to add some syntax to make such definitions more readable, but at the time of 2.2’s release a good syntax was not obvious. Today a good syntax still isn’t obvious but users are asking for easier access to the feature; a new syntactic feature has been added to meet this need.

The new feature is called “function decorators”. The name comes from the idea that classmethod(), staticmethod(), and friends are storing additional information on a function object; they’re decorating functions with more details.

The notation borrows from Java and uses the '@' character as an indicator. Using the new syntax, the example above would be written:

 
 
 
 
  1. class C:
  2. @classmethod
  3. def meth (cls):
  4. ...

The @classmethod is shorthand for the meth=classmethod(meth) assignment. More generally, if you have the following:

 
 
 
 
  1. @A
  2. @B
  3. @C
  4. def f ():
  5. ...

它等价于以下无装饰器的代码:

 
 
 
 
  1. def f(): ...
  2. f = A(B(C(f)))

Decorators must come on the line before a function definition, one decorator per line, and can’t be on the same line as the def statement, meaning that @A def f(): ... is illegal. You can only decorate function definitions, either at the module level or inside a class; you can’t decorate class definitions.

A decorator is just a function that takes the function to be decorated as an argument and returns either the same function or some new object. The return value of the decorator need not be callable (though it typically is), unless further decorators will be applied to the result. It’s easy to write your own decorators. The following simple example just sets an attribute on the function object:

 
 
 
 
  1. >>> def deco(func):
  2. ... func.attr = 'decorated'
  3. ... return func
  4. ...
  5. >>> @deco
  6. ... def f(): pass
  7. ...
  8. >>> f
  9. >>> f.attr
  10. 'decorated'
  11. >>>

As a slightly more realistic example, the following decorator checks that the supplied argument is an integer:

 
 
 
 
  1. def require_int (func):
  2. def wrapper (arg):
  3. assert isinstance(arg, int)
  4. return func(arg)
  5. return wrapper
  6. @require_int
  7. def p1 (arg):
  8. print arg
  9. @require_int
  10. def p2(arg):
  11. print arg*2

An example in PEP 318 contains a fancier version of this idea that lets you both specify the required type and check the returned type.

Decorator functions can take arguments. If arguments are supplied, your decorator function is called with only those arguments and must return a new decorator function; this function must take a single function and return a function, as previously described. In other words, @A @B @C(args) becomes:

 
 
 
 
  1. def f(): ...
  2. _deco = C(args)
  3. f = A(B(_deco(f)))

Getting this right can be slightly brain-bending, but it’s not too difficult.

A small related change makes the func_name attribute of functions writable. This attribute is used to display function names in tracebacks, so decorators should change the name of any new function that’s constructed and returned.

参见

PEP 318 - 函数、方法和类的装饰器

Written by Kevin D. Smith, Jim Jewett, and Skip Montanaro. Several people wrote patches implementing function decorators, but the one that was actually checked in was patch #979728, written by Mark Russell.

https://wiki.python.org/moin/PythonDecoratorLibrary

该Wiki页面包含几个装饰器示例。

PEP 322: 反向迭代

A new built-in function, reversed(seq), takes a sequence and returns an iterator that loops over the elements of the sequence in reverse order.

 
 
 
 
  1. >>> for i in reversed(xrange(1,4)):
  2. ... print i
  3. ...
  4. 3
  5. 2
  6. 1

Compared to extended slicing, such as range(1,4)[::-1], reversed() is easier to read, runs faster, and uses substantially less memory.

Note that reversed() only accepts sequences, not arbitrary iterators. If you want to reverse an iterator, first convert it to a list with list().

 
 
 
 
  1. >>> input = open('/etc/passwd', 'r')
  2. >>> for line in reversed(list(input)):
  3. ... print line
  4. ...
  5. root:*:0:0:System Administrator:/var/root:/bin/tcsh
  6. ...

参见

PEP 322 - 反向迭代

由 Raymond Hettinger 撰写并实现。

PEP 324: 新的子进程模块

The standard library provides a number of ways to execute a subprocess, offering different features and different levels of complexity. os.system(command) is easy to use, but slow (it runs a shell process which executes the command) and dangerous (you have to be careful about escaping the shell’s metacharacters). The popen2 module offers classes that can capture standard output and standard error from the subprocess, but the naming is confusing. The subprocess module cleans this up, providing a unified interface that offers all the features you might need.

Instead of popen2‘s collection of classes, subprocess contains a single class called Popen whose constructor supports a number of different keyword arguments.

 
 
 
 
  1. class Popen(args, bufsize=0, executable=None,
  2. stdin=None, stdout=None, stderr=None,
  3. preexec_fn=None, close_fds=False, shell=False,
  4. cwd=None, env=None, universal_newlines=False,
  5. startupinfo=None, creationflags=0):

args is commonly a sequence of strings that will be the arguments to the program executed as the subprocess. (If the shell argument is true, args can be a string which will then be passed on to the shell for interpretation, just as os.system() does.)

stdin, stdout, and stderr specify what the subprocess’s input, output, and error streams will be. You can provide a file object or a file descriptor, or you can use the constant subprocess.PIPE to create a pipe between the subprocess and the parent.

此构造器有几个方便的选项:

  • close_fds requests that all file descriptors be closed before running the subprocess.

  • cwd specifies the working directory in which the subprocess will be executed (defaulting to whatever the parent’s working directory is).

  • env is a dictionary specifying environment variables.

  • preexec_fn is a function that gets called before the child is started.

  • universal_newlines opens the child’s input and output using Python’s universal newlines feature.

Once you’ve created the Popen instance, you can call its wait() method to pause until the subprocess has exited, poll() to check if it’s exited without pausing, or communicate(data) to send the string data to the subprocess’s standard input. communicate(data) then reads any data that the subprocess has sent to its standard output or standard error, returning a tuple (stdout_data, stderr_data).

call() is a shortcut that passes its arguments along to the Popen constructor, waits for the command to complete, and returns the status code of the subprocess. It can serve as a safer analog to os.system():

 
 
 
 
  1. sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
  2. if sts == 0:
  3. # Success
  4. ...
  5. else:
  6. # dpkg returned an error
  7. ...

The command is invoked without use of the shell. If you really do want to use the shell, you can add shell=True as a keyword argument and provide a string instead of a sequence:

 
 
 
 
  1. sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)

The PEP takes various examples of shell and Python code and shows how they’d be translated into Python code that uses subprocess. Reading this section of the PEP is highly recommended.

参见

PEP 324 - 子进程 - 新的进程模块

由 Peter Åstrand 在 Fredrik Lundh 等人的协助下撰写并实现。

PEP 327: 十进制数据类型

Python has always supported floating-point (FP) numbers, based on the underlying C double type, as a data type. However, while most programming languages provide a floating-point type, many people (even programmers) are unaware that floating-point numbers don’t represent certain decimal fractions accurately. The new Decimal type can represent these fractions accurately, up to a user-specified precision limit.

为什么需要十进制?

The limitations arise from the representation used for floating-point numbers. FP numbers are made up of three components:

  • The sign, which is positive or negative.

  • The mantissa, which is a single-digit binary number followed by a fractional part. For example, 1.01 in base-2 notation is 1 + 0/2 + 1/4, or 1.25 in decimal notation.

  • The exponent, which tells where the decimal point is located in the number represented.

For example, the number 1.25 has positive sign, a mantissa value of 1.01 (in binary), and an exponent of 0 (the decimal point doesn’t need to be shifted). The number 5 has the same sign and mantissa, but the exponent is 2 because the mantissa is multiplied by 4 (2 to the power of the exponent 2); 1.25 * 4 equals 5.

Modern systems usually provide floating-point support that conforms to a standard called IEEE 754. C’s double type is usually implemented as a 64-bit IEEE 754 number, which uses 52 bits of space for the mantissa. This means that numbers can only be specified to 52 bits of precision. If you’re trying to represent numbers whose expansion repeats endlessly, the expansion is cut off after 52 bits. Unfortunately, most software needs to produce output in base 10, and common fractions in base 10 are often repeating decimals in binary. For example, 1.1 decimal is binary 1.0001100110011 ...; .1 = 1/16 + 1/32 + 1/256 plus an infinite number of additional terms. IEEE 754 has to chop off that infinitely repeated decimal after 52 digits, so the representation is slightly inaccurate.

Sometimes you can see this inaccuracy when the number is printed:

 
 
 
 
  1. >>> 1.1
  2. 1.1000000000000001

The inaccuracy isn’t always visible when you print the number because the FP-to-decimal-string conversion is provided by the C library, and most C libraries try to produce sensible output. Even if it’s not displayed, however, the inaccuracy is still there and subsequent operations can magnify the error.

For many applications this doesn’t matter. If I’m plotting points and displaying them on my monitor, the difference between 1.1 and 1.1000000000000001 is too small to be visible. Reports often limit output to a certain number of decimal places, and if you round the number to two or three or even eight decimal places, the error is never apparent. However, for applications where it does matter, it’s a lot of work to implement your own custom arithmetic routines.

因此,创建了 Decimal 类型。

Decimal 类型

A new module, decimal, was added to Python’s standard library. It contains two classes, Decimal and Context. Decimal instances represent numbers, and Context instances are used to wrap up various settings such as the precision and default rounding mode.

Decimal instances are immutable, like regular Python integers and FP numbers; once it’s been created, you can’t change the value an instance represents. Decimal instances can be created from integers or strings:

 
 
 
 
  1. >>> import decimal
  2. >>> decimal.Decimal(1972)
  3. Decimal("1972")
  4. >>> decimal.Decimal("1.1")
  5. Decimal("1.1")

You can also provide tuples containing the sign, the mantissa represented as a tuple of decimal digits, and the exponent:

 
 
 
 
  1. >>> decimal.Decimal((1, (1, 4, 7, 5), -2))
  2. Decimal("-14.75")

Cautionary note: the sign bit is a Boolean value, so 0 is positive and 1 is negative.

Converting from floating-point numbers poses a bit of a problem: should the FP number representing 1.1 turn into the decimal number for exactly 1.1, or for 1.1 plus whatever inaccuracies are introduced? The decision was to dodge the issue and leave such a conversion out of the API. Instead, you should convert the floating-point number into a string using the desired precision and pass the string to the Decimal constructor:

 
 
 
 
  1. >>> f = 1.1
  2. >>> decimal.Decimal(str(f))
  3. Decimal("1.1")
  4. >>> decimal.Decimal('%.12f' % f)
  5. Decimal("1.100000000000")

Once you have Decimal instances, you can perform the usual mathematical operations on them. One limitation: exponentiation requires an integer exponent:

 
 
 
 
  1. >>> a = decimal.Decimal('35.72')
  2. >>> b = decimal.Decimal('1.73')
  3. >>> a+b
  4. Decimal("37.45")
  5. >>> a-b
  6. Decimal("33.99")
  7. >>> a*b
  8. Decimal("61.7956")
  9. >>> a/b
  10. Decimal("20.64739884393063583815028902")
  11. >>> a ** 2
  12. Decimal("1275.9184")
  13. >>> a**b
  14. Traceback (most recent call last):
  15. ...
  16. decimal.InvalidOperation: x ** (non-integer)

You can combine Decimal instances with integers, but not with floating-point numbers:

 
 
 
 
  1. >>> a + 4
  2. Decimal("39.72")
  3. >>> a + 4.5
  4. Traceback (most recent call last):
  5. ...
  6. TypeError: You can interact Decimal only with int, long or Decimal data types.
  7. >>>

Decimal numbers can be used with the math and cmath modules, but note that they’ll be immediately converted to floating-point numbers before the operation is performed, resulting in a possible loss of precision and accuracy. You’ll also get back a regular floating-point number and not a Decimal.

 
 
 
 
  1. >>> import math, cmath
  2. >>> d = decimal.Decimal('123456789012.345')
  3. >>> math.sqrt(d)
  4. 351364.18288201344
  5. >>> cmath.sqrt(-d)
  6. 351364.18288201344j

Decimal instances have a sqrt() method that returns a Decimal, but if you need other things such as trigonometric functions you’ll have to implement them.

 
 
 
 
  1. >>> d.sqrt()
  2. Decimal("351364.1828820134592177245001")

Context 类型

Instances of the Context class encapsulate several settings for decimal operations:

  • prec is the precision, the number of decimal places.

  • rounding specifies the rounding mode. The decimal module has constants for the various possibilities: ROUND_DOWN, ROUND_CEILING, ROUND_HALF_EVEN, and various others.

  • traps is a dictionary specifying what happens on encountering certain error conditions: either an exception is raised or a value is returned. Some examples of error conditions are division by zero, loss of precision, and overflow.

There’s a thread-local default context available by calling getcontext(); you can change the properties of this context to alter the default precision, rounding, or trap handling. The following example shows the effect of changing the precision of the default context:

 
 
 
 
  1. >>> decimal.getcontext().prec
  2. 28
  3. >>> decimal.Decimal(1) / decimal.Decimal(7)
  4. Decimal("0.1428571428571428571428571429")
  5. >>> decimal.getcontext().prec = 9
  6. >>> decimal.Decimal(1) / decimal.Decimal(7)
  7. Decimal("0.142857143")

The default action for error conditions is selectable; the module can either return a special value such as infinity or not-a-number, or exceptions can be raised:

 
 
 
 
  1. >>> decimal.Decimal(1) / decimal.Decimal(0)
  2. Traceback (most recent call last):
  3. ...
  4. decimal.DivisionByZero: x / 0
  5. >>> decimal.getcontext().traps[decimal.DivisionByZero] = False
  6. >>> decimal.Decimal(1) / decimal.Decimal(0)
  7. Decimal("Infinity")
  8. >>>

The Context instance also has various methods for formatting numbers such as to_eng_string() and to_sci_string().

For more information, see the documentation for the decimal module, which includes a quick-start tutorial and a reference.

参见

PEP 327 - 十进数据类型

由 Facundo Batista 撰写,由Facundo Batista, Eric Price, Raymond Hettinger, Aahz 和 Tim Peters 实现。

http://www.lahey.com/float.htm

The article uses Fortran code to illustrate many of the problems that floating-point inaccuracy can cause.

http://speleotrove.com/decimal/

A description of a decimal-based representation. This representation is being proposed as a standard, and underlies the new Python decimal type. Much of this material was written by Mike Cowlishaw, designer of the Rexx language.

PEP 328: 多行导入

One language change is a small syntactic tweak aimed at making it easier to import many names from a module. In a from module import names statement, names is a sequence of names separated by commas. If the sequence is very long, you can either write multiple imports from the same module, or you can use backslashes to escape the line endings like this:

 
 
 
 
  1. from SimpleXMLRPCServer import SimpleXMLRPCServer,\
  2. SimpleXMLRPCRequestHandler,\
  3. CGIXMLRPCRequestHandler,\
  4. resolve_dotted_attribute

The syntactic change in Python 2.4 simply allows putting the names within parentheses. Python ignores newlines within a parenthesized expression, so the backslashes are no longer needed:

 
 
 
 
  1. from SimpleXMLRPCServer import (SimpleXMLRPCServer,
  2. SimpleXMLRPCRequestHandler,
  3. CGIXMLRPCRequestHandler,
  4. resolve_dotted_attribute)

The PEP also proposes that all import statements be absolute imports, with a leading . character to indicate a relative import. This part of the PEP was not implemented for Python 2.4, but was completed for Python 2.5.

参见

PEP 328 - 导入:多行和绝对/相对导入

由 Aahz 撰写,多行导入由 Dima Dorfman 实现。

PEP 331: Locale-Independent Float/String Conversions

The locale modules lets Python software select various conversions and display conventions that are localized to a particular country or language. However, the module was careful to not change the numeric locale because various functions in Python’s implementation required that the numeric locale remain set to the 'C' locale. Often this was because the code was using the C library’s atof() function.

Not setting the numeric locale caused trouble for extensions that used third-party C libraries, however, because they wouldn’t have the correct locale set. The motivating example was GTK+, whose user interface widgets weren’t displaying numbers in the current locale.

The solution described in the PEP is to add three new functions to the Python API that perform ASCII-only conversions, ignoring the locale setting:

  • PyOS_ascii_strtod(str, ptr) and PyOS_ascii_atof(str, ptr) both convert a string to a C double.

  • PyOS_ascii_formatd(buffer, buf_len, format, d) converts a double to an ASCII string.

The code for these functions came from the GLib library (https://developer.gnome.org/glib/stable/), whose developers kindly relicensed the relevant functions and donated them to the Python Software Foundation. The locale module can now change the numeric locale, letting extensions such as GTK+ produce the correct results.

参见

PEP 331 - Locale-Independent Float/String Conversions

由Christian R. Reis撰写,由 Gustavo Carneiro 实现。

其他语言特性修改

Here are all of the changes that Python 2.4 makes to the core Python language.

  • Decorators for functions and methods were added (PEP 318).

  • Built-in set() and frozenset() types were added (PEP 218). Other new built-ins include the reversed(seq) function (PEP 322).

  • Generator expressions were added (PEP 289).

  • Certain numeric expressions no longer return values restricted to 32 or 64 bits (PEP 237).

  • You can now put parentheses around the list of names in a from module import names statement (PEP 328).

  • The dict.update() method now accepts the same argument forms as the dict constructor. This includes any mapping, any iterable of key/value pairs, and keyword arguments. (Contributed by Raymond Hettinger.)

  • The string methods ljust(), rjust(), and center() now take an optional argument for specifying a fill character other than a space. (Contributed by Raymond Hettinger.)

  • Strings also gained an rsplit() method that works like the split() method but splits from the end of the string. (Contributed by Sean Reifschneider.)

       
       
       
       
    1. >>> 'www.python.org'.split('.', 1)
    2. ['www', 'python.org']
    3. 'www.python.org'.rsplit('.', 1)
    4. ['www.python', 'org']
  • Three keyword parameters, cmp, key, and reverse, were added to the sort() method of lists. These parameters make some common usages of sort() simpler. All of these parameters are optional.

    For the cmp parameter, the value should be a comparison function that takes two parameters and returns -1, 0, or +1 depending on how the parameters compare. This function will then be used to sort the list. Previously this was the only parameter that could be provided to sort().

    key should be a single-parameter function that takes a list element and returns a comparison key for the element. The list is then sorted using the comparison keys. The following example sorts a list case-insensitively:

       
       
       
       
    1. >>> L = ['A', 'b', 'c', 'D']
    2. >>> L.sort() # Case-sensitive sort
    3. >>> L
    4. ['A', 'D', 'b', 'c']
    5. >>> # Using 'key' parameter to sort list
    6. >>> L.sort(key=lambda x: x.lower())
    7. >>> L
    8. ['A', 'b', 'c', 'D']
    9. >>> # Old-fashioned way
    10. >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
    11. >>> L
    12. ['A', 'b', 'c', 'D']

    The last example, which uses the cmp parameter, is the old way to perform a case-insensitive sort. It works but is slower than using a key parameter. Using key calls lower() method once for each element in the list while using cmp will call it twice for each comparison, so using key saves on invocations of the lower() method.

    For simple key functions and comparison functions, it is often possible to avoid a lambda expression by using an unbound method instead. For example, the above case-insensitive sort is best written as:

       
       
       
       
    1. >>> L.sort(key=str.lower)
    2. >>> L
    3. ['A', 'b', 'c', 'D']

    Finally, the reverse parameter takes a Boolean value. If the value is true, the list will be sorted into reverse order. Instead of L.sort(); L.reverse(), you can now write L.sort(reverse=True).

    The results of sorting are now guaranteed to be stable. This means that two entries with equal keys will be returned in the same order as they were input. For example, you can sort a list of people by name, and then sort the list by age, resulting in a list sorted by age where people with the same age are in name-sorted order.

    (All changes to sort() contributed by Raymond Hettinger.)

  • There is a new built-in function sorted(iterable) that works like the in-place list.sort() method but can be used in expressions. The differences are:

  • 输入可以是任意可迭代对象;

  • a newly formed copy is sorted, leaving the original intact; and

  • the expression returns the new sorted copy

       
       
       
       
    1. >>> L = [9,7,8,3,2,4,1,6,5]
    2. >>> [10+i for i in sorted(L)] # usable in a list comprehension
    3. [11, 12, 13, 14, 15, 16, 17, 18, 19]
    4. >>> L # original is left unchanged
    5. [9,7,8,3,2,4,1,6,5]
    6. >>> sorted('Monty Python') # any iterable may be an input
    7. [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y']
    8. >>> # List the contents of a dict sorted by key values
    9. >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5)
    10. >>> for k, v in sorted(colormap.iteritems()):
    11. ... print k, v
    12. ...
    13. black 4
    14. blue 2
    15. green 3
    16. red 1
    17. yellow 5

    (由 Raymond Hettinger 贡献。)

  • Integer operations will no longer trigger an OverflowWarning. The OverflowWarning warning will disappear in Python 2.5.

  • The interpreter gained a new switch, -m, that takes a name, searches for the corresponding module on sys.path, and runs the module as a script. For example, you can now run the Python profiler with python -m profile. (Contributed by Nick Coghlan.)

  • The eval(expr, globals, locals) and execfile(filename, globals, locals) functions and the exec statement now accept any mapping type for the locals parameter. Previously this had to be a regular Python dictionary. (Contributed by Raymond Hettinger.)

  • The zip() built-in function and itertools.izip() now return an empty list if called with no arguments. Previously they raised a TypeError exception. This makes them more suitable for use with variable length argument lists:

       
       
       
       
    1. >>> def transpose(array):
    2. ... return zip(*array)
    3. ...
    4. >>> transpose([(1,2,3), (4,5,6)])
    5. [(1, 4), (2, 5), (3, 6)]
    6. >>> transpose([])
    7. []

    (由 Raymond Hettinger 贡献。)

  • Encountering a failure while importing a module no longer leaves a partially initialized module object in sys.modules. The incomplete module object left behind would fool further imports of the same module into succeeding, leading to confusing errors. (Fixed by Tim Peters.)

  • None 现在是一个常量;将一个新值绑定到名称 None 的代码现在会造成语法错误。 (由 Raymond Hettinger 贡献。)

性能优化

  • The inner loops for list and tuple slicing were optimized and now run about one-third faster. The inner loops for dictionaries were also optimized, resulting in performance boosts for keys(), values(), items(), iterkeys(), itervalues(), and iteritems(). (Contributed by Raymond Hettinger.)

  • The machinery for growing and shrinking lists was optimized for speed and for space efficiency. Appending and popping from lists now runs faster due to more efficient code paths and less frequent use of the underlying system realloc(). List comprehensions also benefit. list.extend() was also optimized and no longer converts its argument into a temporary list before extending the base list. (Contributed by Raymond Hettinger.)

  • list(), tuple(), map(), filter(), and zip() now run several times faster with non-sequence arguments that supply a __len__() 文章题目:创新互联Python教程:Python2.4有什么新变化
    网页地址:http://www.mswzjz.com/qtweb/news6/162656.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联