我发现这个方法在python中链接,但即使有了它我也无法理解Python中的方法链接.
这里的目标是两个:解决编码问题并理解方法链(考虑到我仍然没有100%对callables有信心).
直到问题定义.
我想要一个有两个方法的类:一个设置object ='line'的参数,另一个设置覆盖'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')
可悲的是,通过这段代码,我可以实现我的目标
a = foo() a.bar().line().bar().bar().line().my_print()
但是我希望通过编写这段代码来获得相同的结果
a = foo() a.bar.line.bar.bar.line.my_print()
我该如何实现这一目标?我想我定义__call__
方法的方法有点不对劲.在此先感谢您的帮助.
方法链只是能够添加.second_func()
到任何.first_func()
返回.通过确保所有可链接方法返回,相当容易实现self
.(注意,这与此无关__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
通过忽略它们返回的值来以非链式方式使用对象:
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'
摆脱()
调用语法的问题是与方法链接完全不同的概念.如果您想要链属性,并让这些属性改变其对象,请使用@property
装饰器.(但通过属性变异对象似乎很危险.最好使用方法并用动词命名:例如,.set_line()
而不是.line
.)
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'
使用属性(描述符)。
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) @property def line(self): return self(kind='line') @property def bar(self): return self(kind='bar')
注意,尽管如此,您什么也不会覆盖,修改不能就地进行(顺便说一句,这很好)。无论如何,对于大多数现实情况而言,这似乎不是一个好的设计选择,因为在某些时候您的方法将需要参数。