Python Advanced1:less than class
This page is About:
- List comprehensions
- Iterator & Generators
- Discriptors & Properties
- Decrators
- Contextlib
- list comprehensions
- vectorization 矢量化编程的概念
- enumerate() 遍历list同时得到index,value. 可用于提高效率,尤其在矢量化编程中。
- VS map() and / or filter(): map() and / or filter(), list comprehensions 可以解决类似的一些问题,但是通常列表推导的效率、可读性更高。
- Q: 为什么for循环的执行速度会比较慢?
>>> [i for i in range(1,10) if i%2 == 0 ]
[2, 4, 6, 8]
>>> [i*2 for i in range(1,5)]
[2, 4, 6, 8]
>>> [x for x in range(2, 50) if x not in [j for i in range(2, 8) for j in range(i*2, 50, i)]]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
- iterators & generators 迭代器和生成器
- 迭代器本身是一个底层的的特性和概念,为生成器提供了基础
- 生成器: 当需要一个返回一个的函数,或返回在循环中执行的函数时,就应该考虑生成器。
- 基于yield:暂停一个函数,并返回中间结果
- send()
- next() VS throw(exceptions)
- close(): GeneratorExit exception. 不管什么exception 接到,iterator就结束了,这意味着GeneratorExit。
- ?make code simple, not data: 有许多简单的处理序列值的可迭代函数,要比一个复杂的、每次计算一个值的函数更好些。
>>> def fibonacci():
... a,b = 0,1
... while True:
... yield b
... a, b = b, a+b
>>> f = fibonacci()
>>> f.next()
1
>>> f.next()
1
>>> f.next()
2
>>> f.next()
3
>>> [f.next() for i in range(0,10)]
[5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
>>> def testge():
... print "welcome"
... try:
... print "first try"
... yield "try 1"
... except ValueError:
... print "got exception"
... yield "except 2"
... finally:
... print "finally"
... yield "last 3"
... print "end"
... yield "bye"
...
>>> a=testge()
>>> a.throw(ValueError("error1"))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in testge
ValueError: error1
>>> a.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
>>> b=testge()
>>> b.next()
welcome
first try
'try 1'
>>> b.next()
finally
'last 3'
>>> b.next()
end
'bye'
>>> b.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
- ?用generator编写coroutine协同程序:可以挂起、恢复,并且有多个进入点的函数,例如多任务,管道机制,每个协同程序将消费或生成数据,然后暂停,直到其他数据被传递。
- 生成器表达式: 类似列表推导的语法(代替yield)来构造生成器.
- 用圆括号代替方括号:整个序列和list comprehensions一样都不会事先进行计算.
- 以此来代替yield表达式可以减少序列代码的总量
>>> iter = (x**2 for x in range(1,10) if x%2 == 0 )
>>> for ite in iter:
... print ite
...
4
16
36
64
- itertools模块
- 提供了许多高效迭代器模式,可以用各种方式对数据进行循环操作,此模块中的所有函数返回的迭代器都可以与for循环语句以及其他包含迭代器(如生成器和生成器表达式)的函数联合使用。
- islice, tee, groupby
- islice: 抽取位于流中特定位置的数据,可以看作在每行数据之上的一个滑动窗口。
- tee: 往返式的迭代器
- groupby:uniq迭代器, 当需要在数据上完成一个摘要时,结合sorted函数,可以把相似的元素放到一起。
- ex:使用行程长度编码(RLE)来压缩数据:字符中每组相邻的重复字符将替换成字符本身和重复次数。 LZ77压缩
- itertools的工具都可以自行实现。itertools只是提供了更加成形的解决方案。 一些函数
- 无穷循环器: count, cycle, repeat
- 函数式工具: imap, starmap, ifilter, ifilterfalse, takewhile, dropwhile
- 组合工具: chain, product, permutations, combinations, combinations_with_replacement
- Decrators
- 封装函数和方法,增强一个函数(通常是改变作用域,类型?)。 ?方法和函数的差别?
- ex: @classmethod ,@staticmethod 替代了用对应的方法增强函数的操作。
- 关注所封装的函数或方法的接受和返回的参数,减少introspection
- 常用于: 参数检查;缓存代理;上下文提供者
- ex: 提供xmlrpc的签名认证
- ex: 多线程共享的数据,多重访问的保护锁。
- 封装函数和方法,增强一个函数(通常是改变作用域,类型?)。 ?方法和函数的差别?
- with and contextlib
- enter() 和 exit()之间的步骤
- 和try… finally …相比,with简化了实现过程:对于即使发生一些错误也能进行代码清理
- 关闭一个文件
- socket
- 释放一个锁
- 创建一个临时代码补丁
- 在特殊环境中运行受保护的代码
- contextlib是为了加强with语句,提供上下文机制的模块,它是通过Generator实现的。
- nested, closing
- ?下面的例子我的理解是: @contextmanager 增加了__enter__() 和 exit() 这个上下文。
[anne@BTSOM-1 test]$ cat test.py
from contextlib import contextmanager
@contextmanager
def make_context() :
print 'enter'
try :
yield {}
except RuntimeError, err :
print 'error' , err
finally :
print 'exit'
with make_context() as value :
print value
print "============="
def new_context():
print 'enter'
try:
yield {}
except RuntimeError, err:
print 'error',err
finally:
print 'exit'
with new_context() as value:
print value
[anne@BTSOM-1 test]$ python test.py
enter
{}
exit
=============
Traceback (most recent call last):
File "test.py", line 26, in <module>
with new_context() as value:
AttributeError: __exit__