python 中的 __call__方法在实际环境中的应用
来源:互联网 发布:架子鼓软件 编辑:程序博客网 时间:2024/06/06 19:31
用一句话描述是,
Python 的 __call__
方法可以让类的实例具有类似于函数的行为,通常用于定义和初始化一些带有上下文的函数。
既然说是妙处,那不得不提及 Python 世界中的那几个经典实现了。
一个例子来源于 bottle 框架源码的 cached_property
(被我改动了一些细节,但用法基本是一样的),为了在逻辑上构成一个封闭的整体,我们把一个实例当作函数来使用:
class CachedProperty(object): _cache = {} def __call__(self, fn): @property @functools.wraps(fn) def wrapped(self): k = '%s:%s' % (id(self), fn.__name__) v = CachedProperty._cache.get(k) if v is None: v = fn(self) CachedProperty._cache[k] = v return v return wrappedcached_property = CachedProperty()
使用的时候可以直接替换掉内置的 property
来缓存动态属性:
class DB(object): def __init__(self, ...): .... @cached_property def conn(self): return create_connection(...) db = DB()db.conn # 创建连接并缓存
还有个更复杂但非常实用的例子,Pipline,把函数封装成支持管道操作的运算过程:
class Pipe(object): def __init__(self, fn): self.fn = fn def __ror__(self, other): return self.fn(other) def __call__(self, *args, **kwargs): op = Pipe(lambda x: self.fn(x, *args, **kwargs)) return op
可以像这样调用:
@Pipedef sort(data, cmp=None, key=None, reverse=False): return sorted(data, cmp=cmp, key=None, reverse=reverse) [{'score': 1}, {'score': 3}, {'score': 2}] | sort(key=lambda x: x['score'])
可以看出,类 Pipe
被当作一个装饰器使用,所以 sort
函数的原始定义被传递给 Pipe.__init__
,构造出一个 Pipe 实例,所以被装饰过的 sort
函数,也就是我们后面使用的那个,实际上是一个 Pipe
类的实例,只是因为它有 __call__
方法,所以可以作为函数来使用。
这种用法在写一些 ORM 框架以及有大量细粒度行为的库时有奇效。
阅读全文
0 0
- python 中的 __call__方法在实际环境中的应用
- python中的__call__方法
- [笔记]Python class中的__call__()方法
- Python class中的__call__()方法
- Python中的__init__,__call__
- Python中的__init__,__call__
- Python字典在实际工作中的应用
- python中的__call__特殊函数
- python中的@与__call__()函数
- Python中的__new__、__init__、__call__三个特殊方法
- 详解Python中的__new__、__init__、__call__三个特殊方法
- Regsvr32在实际中的应用
- 理解python中的__str__, __call__, __init__, __getattr__
- NHibernate在实际项目中的应用
- 设计模式在实际项目中的应用
- UML在实际开发中的应用
- log4net 在.net中的实际应用
- 数据结构在实际开发过程中的应用
- 【机器学习 数据预处理】fit_transform()和transform()的区别
- c++11 new for loops
- linux网络子系统
- printf函数接口的解读
- express向jade传值问题
- python 中的 __call__方法在实际环境中的应用
- Github出现 ssh operation timed out
- Java初学者
- -TEST 12 for NOIP ......(30-300)-----(( ! ))
- Docker 命令大全
- su和sudo
- Unity中的C#与C++交互
- ionic页面
- PullToRefreshScrollView