迭代器(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__(),这个方法是在我们调用被修饰函数时被调用的。
Ref:
http://www.scipy-lectures.org/advanced/advanced_python/index.html#decorators
http://coolshell.cn/articles/11265.html