迭代器(iterators)
迭代器有一個(gè)特點(diǎn),就是每次迭代容器里的一個(gè)數(shù)庐镐,把容器里的數(shù)迭代完之后就會(huì)停止迭代恩商,出現(xiàn) StopIteration
異常”啬妫可以把迭代器理解為洗發(fā)水痕届,每次擠一點(diǎn),擠完了就剩下個(gè)空瓶末患,可以丟掉了研叫。使用容器內(nèi)置函數(shù)__iter__()可以直接生成迭代器,使用iter()函數(shù)也可以生成迭代器璧针。
>>> nums = [1, 2, 3]
>>> iter(nums)
<...iterator object at ...>
#生成一個(gè)迭代器
>>> it = iter(nums)
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
用在for循環(huán)里面:
>>>nums=[1,10,100]
>>>it = nums.__iter__()
>>>sum=0
>>>for i in it:
...: sum=sum+i
...:print sum
111
>>>for i in it:
...: sum=sum+i
...:print sum
0
生成器(generators)
生成器通常由推導(dǎo)式生成嚷炉,例如:
>>> (i for i in nums)
<generator object <genexpr> at 0x...>
>>> list(i for i in nums)
[1, 2, 3]
如果加上中括號(hào)就是列表、加上中括號(hào)就是字典或者集合:
>>> [i for i in nums]
[1, 2, 3]
>>> {i for i in range(3)}
set([0, 1, 2])
>>> {i:i**2 for i in range(3)}
{0: 0, 1: 1, 2: 4}
還有另外一種生成器的表達(dá)方式是yield探橱,當(dāng)next()被調(diào)用時(shí)申屹,就會(huì)執(zhí)行第一個(gè)yield绘证。執(zhí)行完yield語句后,就會(huì)停止哗讥∪履牵看兩個(gè)例子就可以理解:
>>> def f():
... yield 1
... yield 2
>>> f()
<generator object f at 0x...>
>>> gen = f()
>>> next(gen)
1
>>> next(gen)
2
>>> next(gen)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> def f():
... print("-- start --")
... yield 3
... print("-- middle --")
... yield 4
... print("-- finished --")
>>> gen = f()
>>> next(gen)
-- start --
3
>>> next(gen)
-- middle --
4
>>> next(gen)
-- finished --
Traceback (most recent call last):
...
StopIteration
裝飾器(decorators)
假如我們想修正(修飾)一個(gè)已經(jīng)寫好的模塊,又不讓這個(gè)裝飾侵入到原有的模塊代碼中去杆煞,這時(shí)候就需要用到裝飾器啦魏宽。
第一種方法,我們需要寫一個(gè)用來裝飾已有模塊的裝飾函數(shù):
>>> def simple_decorator(function):
... print("doing decoration")
... return function
假如我們想修飾function()這個(gè)函數(shù)决乎,只需在函數(shù)上面加上@修飾器:
>>> @simple_decorator
... def function():
... print("inside function")
doing decoration
>>> function()
inside function
這個(gè)實(shí)際的效果相當(dāng)于:
function = simple_decorator(function)
將要進(jìn)行修飾的函數(shù)function當(dāng)作參數(shù)傳遞到修飾器simple_decorator中队询,然后在進(jìn)行回調(diào),賦值回原來的function.
我們的修飾器也可以加參數(shù):
>>> def decorator_with_arguments(arg):
... print("defining the decorator")
... def _decorator(function):
... print("doing decoration, %r" % arg)
... return function
... return _decorator
>>> @decorator_with_arguments("abc")
... def function():
... print("inside function")
defining the decorator
doing decoration, 'abc'
>>> function()
inside function
實(shí)際上相當(dāng)于:
function = decorator_with_arguments("abc")(function)
那么實(shí)際上decorator_with_arguments("abc")需要返回一個(gè)真正的修飾器來修飾function构诚。例子中是返回_decorator這個(gè)修飾器蚌斩。
當(dāng)含有多個(gè)修飾器時(shí),修飾順序是從下向上的:
>>> @decorator_one
... @decorator_two
... def func():
... pass
就相當(dāng)于:
func = decorator_one(decorator_two(func))
第二種方法范嘱,使用類的方法來修飾函數(shù):
>>> class myDecorator(object):
... def __init__(self, fn):
... print "inside myDecorator.__init__()"
... self.fn = fn
...
... def __call__(self):
... self.fn()
... print "inside myDecorator.__call__()"
...
>>> @myDecorator
... def aFunction():
... print "inside aFunction()"
...
print "Finished decorating aFunction()"
>>>aFunction()
... inside myDecorator.__init__()
... Finished decorating aFunction()
... inside aFunction()
... inside myDecorator.__call__()
使用類的修飾器會(huì)有兩個(gè)成員:
一個(gè)是__init__()送膳,這個(gè)方法是在我們給某個(gè)函數(shù)修飾時(shí)被調(diào)用。
一個(gè)是__call__()丑蛤,這個(gè)方法是在我們調(diào)用被修飾函數(shù)時(shí)被調(diào)用的肠缨。
Ref:
http://www.scipy-lectures.org/advanced/advanced_python/index.html#decorators
http://coolshell.cn/articles/11265.html