首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >python中的方法链接

python中的方法链接
EN

Stack Overflow用户
提问于 2012-08-29 15:34:26
回答 5查看 23.9K关注 0票数 27

(不要与itertools.chain混淆)

我正在阅读以下内容:http://en.wikipedia.org/wiki/Method_chaining

我的问题是:在中实现方法链接的最佳方式是什么?

这是我的尝试:

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了吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2020-02-29 18:52:40

我正在寻找类似的链接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

现在,我可以通过调用以下命令来命名汽车并将其置于驾驶状态:

my_car = Car()
my_car.set_name('Porche').drive()

警告:这只适用于不打算返回任何数据的类函数。

希望这能有所帮助!

票数 8
EN

Stack Overflow用户

发布于 2012-08-29 15:49:54

有一个非常方便的Pipe库,它可能是您问题的答案。例如::

seq = fib() | take_while(lambda x: x < 1000000) \
            | where(lambda x: x % 2) \
            | select(lambda x: x * x) \
            | sum()
票数 22
EN

Stack Overflow用户

发布于 2015-01-30 17:13:10

如果只使用pure functions,这样方法就不会直接修改self.data,而是返回修改后的版本,这是可能的。您还必须返回Chainable实例。

下面是一个使用带有列表的collection pipelining的例子:

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

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12172934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档