(不要与itertools.chain混淆)
我读了以下情况: http://en.wikipedia.org/wiki/Method_chaining
我的问题是: 什么是在Python中实现方法链的最佳方式?
这里是我的尝试:
class chain():
def __init__(self, my_object):
self.o = my_object
def __getattr__(self, attr):
x = getattr(self.o, attr)
if hasattr(x, '__call__'):
method = x
return lambda *args: self if method(*args) is None else method(*args)
else:
prop = x
return prop
list_ = chain([1, 2, 3, 0])
print list_.extend([9, 5]).sort().reverse()
"""
C:\Python27\python.exe C:/Users/Robert/PycharmProjects/contests/sof.py
[9, 5, 3, 2, 1, 0]
"""
一个问题是,如果在调用method(*args)
修改self.o
但不返回None
。 (那么我应该回到self
或返回什么method(*args)
返回)。
有没有人有实施链接的更好的方法? 可能有很多方法可以做到这一点。
如果我只是假设的方法总是返回None
所以我可能总是返回self.o
?
有一个非常方便的Pipe
可能是回答你的问题库。 例如::
seq = fib() | take_while(lambda x: x < 1000000) \
| where(lambda x: x % 2) \
| select(lambda x: x * x) \
| sum()
这是可能的,如果你只使用纯函数 ,这样的方法没有修改self.data
直接,而是返回修改后的版本。 你还必须返回Chainable
实例。
下面是使用一个例子收集流水线处理列表:
import itertools
try:
import builtins
except ImportError:
import __builtin__ as builtins
class Chainable(object):
def __init__(self, data, method=None):
self.data = data
self.method = method
def __getattr__(self, name):
try:
method = getattr(self.data, name)
except AttributeError:
try:
method = getattr(builtins, name)
except AttributeError:
method = getattr(itertools, name)
return Chainable(self.data, method)
def __call__(self, *args, **kwargs):
try:
return Chainable(list(self.method(self.data, *args, **kwargs)))
except TypeError:
return Chainable(list(self.method(args[0], self.data, **kwargs)))
使用这样的:
chainable_list = Chainable([3, 1, 2, 0])
(chainable_list
.chain([11,8,6,7,9,4,5])
.sorted()
.reversed()
.ifilter(lambda x: x%2)
.islice(3)
.data)
>> [11, 9, 7]
需要注意的是.chain
指itertools.chain
而不是OP的chain
。
这里不会是被链接允许任何对象的任何方法,任何普通的方式,因为你无法知道什么样的值方法返回,为什么不知道具体的方法是如何工作的。 方法可能会返回None
任何理由; 它并不总是意味着该法修改的对象。 同样,也有一个返回值仍然方法可能不会返回可以链接的值。 有没有办法像链的方法list.index
: fakeList.index(1).sort()
不能有工作的很大希望,因为整点index
是它返回一个数字,而且这个数字意味着什么,以及不可忽视的只是链条原来的对象。
如果你只是摆弄周围用Python的内建类型链某些特定的方法(比如排序和删除),你最好只是包装那些特定方法明确(通过在包装类中重写它们),而不是试图做一个与一般的机制__getattr__
。