rob*_*ing 22 python method-chaining
(不要与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]
"""
Run Code Online (Sandbox Code Playgroud)
一个问题是如果调用method(*args)
修改self.o
但不返回None
.(然后我应该返回self
或返回什么method(*args)
返回).
有没有人有更好的方法来实现链接?可能有很多方法可以做到这一点.
我应该假设一个方法总是返回None
所以我可能总是返回self.o
?
Zau*_*bov 21
有一个非常方便的Pipe
库,可能是你的问题的答案.例如::
seq = fib() | take_while(lambda x: x < 1000000) \
| where(lambda x: x % 2) \
| select(lambda x: x * x) \
| sum()
Run Code Online (Sandbox Code Playgroud)
reu*_*ano 16
如果您仅使用纯函数,则方法可以不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)))
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
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]
Run Code Online (Sandbox Code Playgroud)
注意,.chain
指的是itertools.chain
OP而不是OP chain
.
我正在寻找类似于链接Class
函数的东西,但没有找到好的答案,所以这是我所做的并且认为是一种非常简单的链接方法:只需返回self
对象。
所以这是我的设置:
Class Car():
def __init__(self, name=None):
self.name = name
self.mode = 'init'
def set_name(self, name):
self.name = name
return self
def drive(self):
self.mode = 'drive'
return self
Run Code Online (Sandbox Code Playgroud)
现在我可以通过调用以下方法命名汽车并将其置于驱动状态:
my_car = Car()
my_car.set_name('Porche').drive()
Run Code Online (Sandbox Code Playgroud)
警告:这仅适用于不打算返回任何数据的类函数。
希望这可以帮助!