基本方法链 [英] Basic method chaining
问题描述
我发现了这个python中的方法链,但即使有了它我也无法理解Python 中的方法链.
I found this method chaining in python, but even with it I couldn't understand method chaining in Python.
这里的目标有两个:解决编码问题和理解方法链(鉴于我对可调用对象仍然不是 100% 有信心).
Here the goals are two: solve the coding problem and understand method chaining (given that I am still not 100% confident with callables).
直到问题定义.
我想要一个有两种方法的类:一个设置对象的参数 = 'line',另一个覆盖'bar'.
I want a class that has two methods: one sets a parameter of the object = 'line' and the other overwrites to 'bar'.
这是我目前得到的:
class foo():
def __init__(self, kind=None):
self.kind = kind
def __call__(self, kind=None):
return foo(kind=kind)
def my_print(self):
print (self.kind)
def line(self):
return self(kind='line')
def bar(self):
return self(kind='bar')
遗憾的是,使用此代码我可以实现我的目标
Sadly, with this code I can achieve my goal doing this
a = foo()
a.bar().line().bar().bar().line().my_print()
但我想通过编写此代码获得相同的结果
But I would like to obtain the same result by writing this code
a = foo()
a.bar.line.bar.bar.line.my_print()
我如何实现这一目标?我想我定义 __call__
方法的方式有问题.预先感谢您的帮助.
How do I achieve this? I guess is something wrong in how I defined the __call__
method. Thanks in advance for your help.
推荐答案
方法链只是能够将 .second_func()
添加到 .first_func()
返回的任何内容.通过确保所有可链接的方法都返回 self
,它很容易实现.(请注意,这与 __call()__
无关).
Method chaining is simply being able to add .second_func()
to whatever .first_func()
returns. It is fairly easily implemented by ensuring that all chainable methods return self
. (Note that this has nothing to do with __call()__
).
class foo():
def __init__(self, kind=None):
self.kind = kind
def my_print(self):
print (self.kind)
return self
def line(self):
self.kind = 'line'
return self
def bar(self):
self.kind='bar'
return self
您可以通过忽略返回值以非链式方式使用 foo
对象:
You can use foo
objects in a non-chained way by ignoring their returned values:
a = foo()
a.line()
a.my_print()
a.bar()
a.my_print()
assert a.kind == 'bar'
或者,由于现在每个函数都返回对象本身,您可以操作直接在返回值上.您可以使用具有以下等效代码的方法链:
Or, since every function now returns the object itself, you can operate directly on the returned value. You can use method chaining with this equivalent code:
b = foo()
b.line().my_print().bar().my_print()
assert b.kind == 'bar'
甚至:
c = foo().line().my_print().bar().my_print()
assert c.kind == 'bar'
摆脱()
调用语法的问题是一个完全独立于方法链的概念.如果您想要链属性,并让这些属性改变它们的对象,请使用 @property
装饰器.(但是通过属性改变对象似乎很危险.最好使用一个方法并用动词命名它:例如,.set_line()
而不是 .line
.)
The question of getting rid of the ()
calling syntax is a completely separate concept from method chaining. If you want chain properties, and have those properties mutate their object, use the @property
decorator. (But mutating objects via a property seems dangerous. Better to use a method and name it with a verb: .set_line()
instead of .line
, for example.)
class foo():
def __init__(self, kind=None):
self.kind = kind
def my_print(self):
print (self.kind)
return self
@property
def line(self):
self.kind = 'line'
return self
@property
def bar(self):
self.kind='bar'
return self
a = foo()
a.line
a.my_print()
a.bar
a.my_print()
assert a.kind == 'bar'
b = foo()
b.line.my_print().bar.my_print()
assert b.kind == 'bar'
c = foo().line.my_print().bar.my_print()
assert c.kind == 'bar'
这篇关于基本方法链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!