features of Python
From: http://stackoverflow.com/questions/101268/hidden-features-of-python
-
Chaining comparison operators:
>>> x = 5
>>> 1 < x < 10
True
>>> x < 10 < x*10 < 100
True
>>> 10 > x <= 9
True
>>> 5 == x > 4
True
In case you’re thinking it’s doing, ‘1 < x’, which comes out as True, and then comparing ‘True < 10′, which is also True, then no, that’s really not what happens (see the last example.) It’s really translating into ‘1 < x and x < 10′, and ‘x < 10 and 10 < x * 10 and x*10 < 100′, but with less typing and each term is only evaluated once.
-
Readable regular expressions
In Python you can split a regular expression over multiple lines, name your matches and insert comments.
Example verbose syntax (from Dive into Python):
>>> pattern = “”"
^ # beginning of string
M{0,4} # thousands – 0 to 4 M’s
(CM|CD|D?C{0,3}) # hundreds – 900 (CM), 400 (CD), 0-300 (0 to 3 C’s),
# or 500-800 (D, followed by 0 to 3 C’s)
(XC|XL|L?X{0,3}) # tens – 90 (XC), 40 (XL), 0-30 (0 to 3 X’s),
# or 50-80 (L, followed by 0 to 3 X’s)
(IX|IV|V?I{0,3}) # ones – 9 (IX), 4 (IV), 0-3 (0 to 3 I’s),
# or 5-8 (V, followed by 0 to 3 I’s)
$ # end of string
“”"
>>> re.search(pattern, ‘M’, re.VERBOSE)
Example naming matches (from Regular Expression HOWTO)
>>> p = re.compile(r‘(?P<word>\b\w+\b)’)
>>> m = p.search( ‘(((( Lots of punctuation )))’ )
>>> m.group(‘word’)
‘Lots’
-
Decorators
Decorators allow to wrap a function or method in another function that can add functionality, modify arguments or results, etc. You write decorators one line above the function definition, beginning with an “at” sign (@).
Example shows a print_args decorator that prints function’s arguments before calling it:
>>> def print_args(function):
>>> def wrapper(*args, **kwargs):
>>> print
‘Arguments:’, args, kwargs
>>> return
function(*args, **kwargs)
>>> return wrapper
>>> @print_args
>>> def write(text):
>>> print text
>>> write(‘foo’)
Arguments: (‘foo’,) {}
foo
-
iter() can take a callable argument
For instance:
def seek_next_line(f):
for c in iter(lambda: f.read(1),‘\n’):
pass
The iter(callable, until_value) calls repetitively the callable and yields its result until the callable returns _until_value_.
-
Creating generators objects
If you write
x=(n for n in foo if bar(n))
you can get out the generator and assign it to x. Now it means you can do
for n in x:
The advantage of this is that you don’t need intermediate storage, which you would need if you did
x = [n for n in foo if bar(n)]
In some cases this can lead to significant speed up.
-
Futures and the “With” Statement
There’s a special module in Python called __future__. Some new language features end up in this module for testing, and to use them you have to explicitly import them from here. One such feature which is a favorite of mine is the “with” statement, which is currently present in __future__ in version 2.5, but will be part of the language in the soon-to-be-released 2.6 and 3.0 versions.
The reason it is in __future__ is because it makes both with and as keywords, which could break existing code.
I have used the “with” statement in 2.5 a lot because I think it’s a very useful construct, here is a quick demo:
from __future__ import with_statement
with open(‘foo.txt’, ‘w’) as f:
f.write(‘hello!’)
What’s happening here behind the scenes, is that the “with” statement calls the special __enter__ and__exit__ methods on the file object. Exception details are also passed to __exit__ if any exception was raised from the with statement body, allowing for exception handling to happen there.
What this does for you in this particular case is that it guarantees that the file is closed when execution falls out of scope of the “with” statement’s body, regardless if that occurs naturally or whether an exception was thrown. It is basically a way of abstracting away common error-handling code.
Other common use cases for this include locking with threads and database transactions.
For more information on how to use this and how to implement your own “with” statement compatible objects read PEP 343
-
The step argument in slice operators. For example:
a = [1,2,3,4,5]
>>> a[::2] # iterate over the whole list in 2-increments
[1,3,5]
The special case x[::-1] is a useful idiom for ‘x reversed’.
>>> a[::-1]
[5,4,3,2,1]
-
From 2.5 onwards dicts have a special method __missing__ that is invoked for missing items:
>>> class
MyDict(dict):
… def __missing__(self, key):
… self[key] = rv = []
… return rv
…
>>> m = MyDict()
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{‘foo’: [1, 2]}
There is also a dict subclass in collections called defaultdict that does pretty much the same but calls a function without arguments for not existing items:
>>> from collections import defaultdict
>>> m = defaultdict(list)
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{‘foo’: [1, 2]}
I recommend converting such dicts to regular dicts before passing them to functions that don’t expect such subclasses. A lot of code uses d[a_key] and catches KeyErrors to check if an item exists which would add a new item to the dict.
-
Doctest: documentation and unit-testing at the same time.
Example extracted fom python documentation:
def factorial(n):
“”"Return the factorial of n, an exact integer >= 0.
If the result is small enough to fit in an int, return an int.
Else return a long.
>>> [factorial(n) for n in range(6)]
[1, 1, 2, 6, 24, 120]
>>> factorial(-1)
Traceback (most recent call last):
…
ValueError: n must be >= 0
Factorials of floats are OK, but the float must be an exact integer:
“”"
import math
if
not n >= 0:
raise
ValueError(“n must be >= 0″)
if math.floor(n) != n:
raise
ValueError(“n must be exact integer”)
if n+1 == n: # catch a value like 1e300
raise
OverflowError(“n too large”)
result = 1
factor = 2
while factor <= n:
result *= factor
factor += 1
return result
def _test():
import doctest
doctest.testmod()
if __name__ == “__main__”:
_test()
-
Descriptors
They’re the magic behind a whole bunch of core Python features.
When you use dotted access to look up a member (eg, x.y), Python first looks for the member in the instance dictionary. If it’s not found, it looks for it in the class dictionary. If it finds it in the class dictionary, and the object implements the descriptor protocol, instead of just returning it, Python executes it. A descriptor is any class that implements the get, set, or del methods.
Here’s how you’d implement your own (read-only) version of property using descriptors:
class
Property(object):
def __init__(self, fget):
self.fget = fget
def __get__(self, obj, type):
if obj is
None:
return
self
return
self.fget(obj)
and you’d use it just like the built-in property():
class
MyClass(object):
@Property
def foo(self):
return
“Foo!”
Descriptors are used in Python to implement properties, bound methods, static methods, class methods and slots, amongst other things. Understanding them makes it easy to see why a lot of things that previously looked like Python ‘quirks’ are the way they are.
Raymond Hettinger has an excellent tutorial that does a much better job of describing them than I do.
-
Sending values into generator functions. For example having this function:
def mygen():
“”"Yield 5 until something else is passed back via send()”"”
a = 5
while
True:
f = yield(a) #yield a and possibly get f in return
if f: a = f #store the new value
You can:
>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7) #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7
-
One line Variable value swapping
>>> a = 10
>>> b = 5
>>> a, b = b, a
>>> print a
5
>>> print b
10
a will have the value of b and so on.
This is a side effect of python packing and unpacking feature.
-
enumerate
Wrap an iterable with enumerate and it will yield the item along with it’s index.
For example:
>>> a = ['a', 'b', 'c', 'd', 'e']
>>> for index, item in enumerate(a): print index, item
…
0 a
1 b
2 c
3 d
4 e
>>>
-
Creating new types at runtime
>>> NewType = type(“NewType”, (object,), {“x”: “hello”})
>>> n = NewType()
>>> n.x
“hello”
which is exactly the same as
>>> class
NewType(object):
>>> x = “hello”
>>> n = NewType()
>>> n.x
“hello”
Probably not the most useful thing, but nice to know.
Edit: Fixed name of new type, should be NewType to be the exact same thing as with class statement.
查看更多:http://stackoverflow.com/questions/101268/hidden-features-of-python
这个页面里收集了很多python技巧
Onenote不错,再试一下Onenote发帖,呵呵

最新评论