python的一些使用技巧
前言
我太喜欢python这门语言了,以至于我总会忍不住跟身边的人安利这门语言。
本篇博客并不是python的入门教程,而是给那些学习了python但还可以进阶的人看的。有些技巧如果使用得当,可以极大的简化你的代码。
AutoVivification
autovivification是Perl语言的一个特性,它会在你每次引用一个值未定义的属性时为你自动创建数组或者字典。 这个特性允许你在不需要预先声明变量的存在和完整的结构前, 就可以直接来引用它和它任意的子元素。
AutoVivification的一种实现方法如下:
class AutoVivification(dict): """Implementation of perl's autovivification feature.""" def __getitem__(self, item): try: return dict.__getitem__(self, item) except KeyError: value = self[item] = type(self)() return value
我们可以这样子来使用AutoVivification:
weather = AutoVivification()weather['china']['guangdong']['shenzhen'] = 'sunny'weather['china']['hubei']['wuhan'] = 'windy'weather['USA']['California']['Los Angeles'] = 'sunny'print weather结果输出:{'china': {'hubei': {'wuhan': 'windy'}, 'guangdong': {'shenzhen': 'sunny'}}, 'USA': {'California': {'Los Angeles': 'sunny'}}}
创建层级结构复杂的字典类型就是这么随心所欲,而且拥有dict的所有特性.
autovivification还有另一种实现方法,直接改写dict的__missing__
方法
class AutoVivification(dict): """Implementation of perl's autovivification feature.""" def __missing__(self, key): value = self[key] = type(self)() return value
修饰器
装饰器Python面向切面编程的实现。装饰器可以为已经存在的对象添加额外的功能,可以将大量函数中的共同功能抽离出来复用.
比如说我们有一个需求,需要统计每一个函数的运行时间.如果我们要复用这部分"计算时间消耗"的代码,用修饰器可以这样子实现.
import timeimport functoolsdef time_calc(func): @functools.wraps(func) def wrapper(*args, **kwargs): start = time.time() func(*args, **kwargs) end = time.time() print 'used-time:', end - start return wrapper@time_calcdef foo_1(second): time.sleep(second) print 'foo_1 exit'@time_calcdef foo_2(a, b=1): time.sleep(1) print 'foo_2 exit'foo_1(1)foo_2(1, b=2)
这样子,"计算时间消耗"的逻辑我们就不需要在多个函数中一一实现了,而是通过修饰器time_calc,加在其他函数的上面解决了. 如果上面的例子不够清楚,可以移步另一篇对python修饰器的入门使用讲解更详细的文章
一个函数允许加上多个修饰器,而且修饰器的执行顺序是自下向上运行.
比如我们又定义了一个do_nothing
def do_nothing(func): @functools.wraps(func) def wrapper(*args, **kwargs): func(*args, **kwargs) print 'after func, do nothing...' return wrapper
然后修饰foo_1,可以看到输出是由下往上执行的.
@time_calc@do_nothingdef foo_1(second): time.sleep(second) print 'foo_1 exit'foo_1(1)输出:foo_1 exitafter func, do nothing...used-time: 1.00242614746
此外,修饰器还可以带上自己的参数.我们只需要让修饰器的写法上稍微变一下。
def time_calc(machine='machine01'): def outer_wrapper(func): @functools.wraps(func) def wrapper(*args, **kwargs): start = time.time() func(*args, **kwargs) end = time.time() print machine, 'used-time:', end - start return wrapper return outer_wrapper@time_calc(machine='machine2')def foo_1(second): time.sleep(second) print 'foo_1 exit'foo_1(1)
metaclass的使用
metaclass 是巧妙使用python的一个利器。Django的models.Model 就是使用了该利器来实现简单易用的ORM的。这里限于篇幅不展开介绍,有兴趣的可以移步
魔术方法
在Python中,所有以"__"双下划线包起来的方法,都统称为"魔术方法"。 有些魔术方法,巧妙使用它可以构造出非常优美的代码,比如将复杂的逻辑封装成简单的API。
关于魔术方法的介绍和举例,可以移步,那里有更多的介绍。
扩展
- python程序员经常犯的10个错误: