Python筆記:迭代器、生成器、修飾器
阿新 • • 發佈:2019-01-10
迭代器(iterators)
迭代器有一個特點,就是每次迭代容器裡的一個數,把容器裡的數迭代完之後就會停止迭代,出現 StopIteration
異常。可以把迭代器理解為洗髮水,每次擠一點,擠完了就剩下個空瓶,可以丟掉了。使用容器內建函式__iter__()可以直接生成迭代器,使用iter()函式也可以生成迭代器。
>>> nums = [1, 2, 3]
>>> iter(nums)
<...iterator object at ...>
#生成一個迭代器
>>> 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迴圈裡面:
>>>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)
生成器通常由推導式生成,例如:
>>> (i for i in nums)
<generator object <genexpr> at 0x...>
>>> list(i for i in nums)
[1, 2, 3]
如果加上中括號就是列表、加上中括號就是字典或者集合:
>>> [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}
還有另外一種生成器的表達方式是yield,當next()被呼叫時,就會執行第一個yield。執行完yield語句後,就會停止。看兩個例子就可以理解:
>>> 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)
假如我們想修正(修飾)一個已經寫好的模組,又不讓這個裝飾侵入到原有的模組程式碼中去,這時候就需要用到裝飾器啦。
第一種方法,我們需要寫一個用來裝飾已有模組的裝飾函式:
>>> def simple_decorator(function):
... print("doing decoration")
... return function
假如我們想修飾function()這個函式,只需在函式上面加上@修飾器:
>>> @simple_decorator
... def function():
... print("inside function")
doing decoration
>>> function()
inside function
這個實際的效果相當於:
function = simple_decorator(function)
將要進行修飾的函式function當作引數傳遞到修飾器simple_decorator中,然後在進行回撥,賦值回原來的function.
我們的修飾器也可以加引數:
>>> 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
實際上相當於:
function = decorator_with_arguments("abc")(function)
那麼實際上decorator_with_arguments(“abc”)需要返回一個真正的修飾器來修飾function。例子中是返回_decorator這個修飾器。
當含有多個修飾器時,修飾順序是從下向上的:
>>> @decorator_one
... @decorator_two
... def func():
... pass
就相當於:
func = decorator_one(decorator_two(func))
第二種方法,使用類的方法來修飾函式:
>>> 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__()
使用類的修飾器會有兩個成員:
一個是__init__(),這個方法是在我們給某個函式修飾時被呼叫。
一個是__call__(),這個方法是在我們呼叫被修飾函式時被呼叫的。