基本方法链 [英] Basic method chaining

查看:65
本文介绍了基本方法链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了这个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆