>>> 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)
>>> p = re.compile(r'(?P<word>\b\w+\b)')>>> m = p.search( '(((( Lots of punctuation )))' )>>> m.group('word')'Lots'
由于字符串文字连接,您还可以在不使用re.VERBOSE的情况下详细编写正则表达式。
>>> 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... )>>> print pattern"^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$"
def mygen():"""Yield 5 until something else is passed back via send()"""a = 5while True:f = (yield a) #yield a and possibly get f in returnif f is not None:a = f #store the new value
您可以:
>>> g = mygen()>>> g.next()5>>> g.next()5>>> g.send(7) #we send this back to the generator7>>> g.next() #now it will yield 7 until we send something else7
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 mathif 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 1e300raise OverflowError("n too large")result = 1factor = 2while factor <= n:result *= factorfactor += 1return result
def _test():import doctestdoctest.testmod()
if __name__ == "__main__":_test()
>>> class C(object):... id = id...>>> C().id()Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: id() takes exactly one argument (0 given)
但是,您可以创建一个小型绑定描述符来实现这一点:
>>> from types import MethodType>>> class bind(object):... def __init__(self, callable):... self.callable = callable... def __get__(self, obj, type=None):... if obj is None:... return self... return MethodType(self.callable, obj, type)...>>> class C(object):... id = bind(id)...>>> C().id()7414064
>>> print "The %(foo)s is %(bar)i." % {'foo': 'answer', 'bar':42}The answer is 42.
>>> foo, bar = 'question', 123
>>> print "The %(foo)s is %(bar)i." % locals()The question is 123.
class FogBugz:...
def __getattr__(self, name):# Let's leave the private stuff to Pythonif name.startswith("__"):raise AttributeError("No such attribute '%s'" % name)
if not self.__handlerCache.has_key(name):def handler(**kwargs):return self.__makerequest(name, **kwargs)self.__handlerCache[name] = handlerreturn self.__handlerCache[name]...
>>> re.compile("""^ # start of a line\[font # the font tag(?:=(?P<size> # optional [font=+size][-+][0-9]{1,2} # size specification))?\] # end of tag(.*?) # text between the tags\[/font\] # end of the tag""", re.DEBUG|re.VERBOSE|re.DOTALL)
我认为,很多刚开始学习Python的开发人员忽略了生成器,却没有真正理解它们的用途或了解它们的强大功能。直到我阅读了David M. Beazley关于生成器的PyCon演讲(可用这里),我才意识到它们是多么有用(真的很重要)。那个演讲阐明了对我来说是一种全新的编程方式,我把它推荐给任何对生成器没有深刻理解的人。
from goto import goto, labelfor i in range(1, 10):for j in range(1, 20):for k in range(1, 30):print i, j, kif k == 3:goto .end # breaking out from a deeply nested looplabel .endprint "Finished"
>>> class C(object):... def fun(self):... print "C.a", self...>>> inst = C()>>> inst.fun() # C.a method is executedC.a <__main__.C object at 0x00AE74D0>>>> instancemethod = type(C.fun)>>>>>> def fun2(self):... print "fun2", self...>>> inst.fun = instancemethod(fun2, inst, C) # Now we are replace C.a by fun2>>> inst.fun() # ... and fun2 is executedfun2 <__main__.C object at 0x00AE74D0>
>>> import pprint>>> stuff = sys.path[:]>>> stuff.insert(0, stuff)>>> pprint.pprint(stuff)[<Recursion on list with id=869440>,'','/usr/local/lib/python1.5','/usr/local/lib/python1.5/test','/usr/local/lib/python1.5/sunos5','/usr/local/lib/python1.5/sharedmodules','/usr/local/lib/python1.5/tkinter']
$ pythonPython 2.5.1 (r251:54863, Jan 17 2008, 19:35:17)[GCC 4.0.1 (Apple Inc. build 5465)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> shared_var = "Set in main console">>> import code>>> ic = code.InteractiveConsole({ 'shared_var': shared_var })>>> try:... ic.interact("My custom console banner!")... except SystemExit, e:... print "Got SystemExit!"...My custom console banner!>>> shared_var'Set in main console'>>> shared_var = "Set in sub-console">>> import sys>>> sys.exit()Got SystemExit!>>> shared_var'Set in main console'
>>> a = set([1,2,3,4])>>> b = set([3,4,5,6])>>> a | b # Union{1, 2, 3, 4, 5, 6}>>> a & b # Intersection{3, 4}>>> a < b # SubsetFalse>>> a - b # Difference{1, 2}>>> a ^ b # Symmetric Difference{1, 2, 5, 6}
>>> import thisThe Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!
import re
def Main(haystack):# List of from replacements, can be a regexfinds = ('Hello', 'there', 'Bob')replaces = ('Hi,', 'Fred,', 'how are you?')
def ReplaceFunction(matchobj):for found, rep in zip(matchobj.groups(), replaces):if found != None:return rep
# log errorreturn matchobj.group(0)
named_groups = [ '(%s)' % find for find in finds ]ret = re.sub('|'.join(named_groups), ReplaceFunction, haystack)print ret
if __name__ == '__main__':str = 'Hello there Bob'Main(str)# Prints 'Hi, Fred, how are you?'
>>> reload(a_module)>>> a_module.SomeClass is clsFalse # Because it just got freshly created by reload.>>> obj.method()(old method output)
这里有一种更新它的方法(但考虑用剪刀运行):
>>> obj.__class__ is clsTrue # it's the old class object>>> obj.__class__ = a_module.SomeClass # pick up the new class>>> obj.method()(new method output)
class countCalls(object):""" decorator replaces a function with a "countCalls" instancewhich behaves like the original function, but keeps track of calls
>>> @countCalls... def doNothing():... pass>>> doNothing()>>> doNothing()>>> print doNothing.timesCalled2"""def __init__ (self, functionToTrack):self.functionToTrack = functionToTrackself.timesCalled = 0def __call__ (self, *args, **kwargs):self.timesCalled += 1return self.functionToTrack(*args, **kwargs)
def threadify(function):"""exceptionally simple threading decorator. Just:>>> @threadify... def longOperation(result):... time.sleep(3)... return result>>> A= longOperation("A has finished")>>> B= longOperation("B has finished")
A doesn't have a result yet:>>> print A.resultNone
until we wait for it:>>> print A.awaitResult()A has finished
we could also wait manually - half a second more should be enough for B:>>> time.sleep(0.5); print B.resultB has finished"""class thr (threading.Thread,object):def __init__(self, *args, **kwargs):threading.Thread.__init__ ( self )self.args, self.kwargs = args, kwargsself.result = Noneself.start()def awaitResult(self):self.join()return self.resultdef run(self):self.result=function(*self.args, **self.kwargs)return thr
>>> int('10', 0)10>>> int('0x10', 0)16>>> int('010', 0) # does not work on Python 3.x8>>> int('0o10', 0) # Python >=2.6 and Python 3.x8>>> int('0b10', 0) # Python >=2.6 and Python 3.x2
class Foo(object):def __init__(self, arg1, arg2, **kwargs):#do stuff with arg1 and arg2self.__dict__.update(kwargs)
f = Foo('arg1', 'arg2', bar=20, baz=10)#now f is a Foo object with two extra attributes
这可被利用来向对象任意添加属性和函数。这也可以被利用来创建快速脏struct类型。
class struct(object):def __init__(**kwargs):self.__dict__.update(kwargs)
s = struct(foo=10, bar=11, baz="i'm a string!')
class Colors(object):RED, GREEN, BLUE, YELLOW = (255,0,0), (0,255,0), (0,0,255), (0,255,255)
#now Colors.RED is a 3-tuple that returns the 24-bit 8bpp RGB#value for saturated red
>>> import sys>>> import hamTraceback (most recent call last):File "<stdin>", line 1, in <module>ImportError: No module named ham
# Make the 'ham' module available -- as a non-module object even!>>> sys.modules['ham'] = 'ham, eggs, saussages and spam.'>>> import ham>>> ham'ham, eggs, saussages and spam.'
# Now remove it again.>>> sys.modules['ham'] = None>>> import hamTraceback (most recent call last):File "<stdin>", line 1, in <module>ImportError: No module named ham
这甚至适用于是可用的模块,并且在某种程度上适用于已经进口的模块:
>>> import os# Stop future imports of 'os'.>>> sys.modules['os'] = None>>> import osTraceback (most recent call last):File "<stdin>", line 1, in <module>ImportError: No module named os# Our old imported module is still available.>>> os<module 'os' from '/usr/lib/python2.5/os.pyc'>
# in 2.6 <= python < 3.0, 3.0 + the print function is nativefrom __future__ import print_function
mylist = ['foo', 'bar', 'some other value', 1,2,3,4]print(*mylist)
def eras(n):last = n + 1sieve = [0,0] + list(range(2, last))sqn = int(round(n ** 0.5))it = (i for i in xrange(2, sqn + 1) if sieve[i])for i in it:sieve[i*i:last:i] = [0] * (n//i - i + 1)return filter(None, sieve)
>>> sql = "select * from some_table \where id > 10">>> print sqlselect * from some_table where id > 10
另一个是使用三重引用:
>>> sql = """select * from some_tablewhere id > 10""">>> print sqlselect * from some_table where id > 10
问题是它们没有缩进(在你的代码中看起来很差)。如果你尝试缩进,它只会打印你放的空格。
我最近发现的第三种解决方案是将字符串分成行并用括号括起来:
>>> sql = ("select * from some_table " # <-- no comma, whitespace at end"where id > 10 ""order by name")>>> print sqlselect * from some_table where id > 10 order by name
注意行之间没有逗号(这不是元组),并且您必须考虑字符串需要的任何尾随/前导空格。顺便说一句,所有这些都适用于占位符(例如"my name is %s" % name)。
% python -m timeit 'r = range(0, 1000)' 'for i in r: pass'10000 loops, best of 3: 48.4 usec per loop
% python -m timeit 'r = xrange(0, 1000)' 'for i in r: pass'10000 loops, best of 3: 37.4 usec per loop