python:概括委托(delegate)方法

标签 python magic-methods

我有一个包含一个或多个数字元素的类。

class Foo:
    # ... other methods ...
    def _update(self, f):
        # ... returns a new Foo() object based on transforming
        #     one or more data members with a function f()
    def __add__(self, k):
        return self._update(lambda x: x.__add__(k))
    def __radd__(self, k):
        return self._update(lambda x: x.__radd__(k))
    def __sub__(self, k):
        return self._update(lambda x: x.__sub__(k))
    def __rsub__(self, k):
        return self._update(lambda x: x.__rsub__(k))
    def __mul__(self, k):
        return self._update(lambda x: x.__mul__(k))
    def __rmul__(self, k):
        return self._update(lambda x: x.__rmul__(k))
    def __div__(self, k):
        return self._update(lambda x: x.__div__(k))
    def __rdiv__(self, k):
        return self._update(lambda x: x.__rdiv__(k))
    # I want to add other numeric methods also

有没有什么方法可以将此概括为所有 numeric methods ,而不必为每个人都这样做?

我只想委托(delegate)数字方法列表中的任何方法。

最佳答案

您想使用 operator module在这里,连同一个(简短的)二进制数字运算符名称列表,为了紧凑而没有下划线:

import operator 

numeric_ops = 'add div floordiv mod mul pow sub truediv'.split()

def delegated_arithmetic(handler):
    def add_op_method(op, cls):
        op_func = getattr(operator, op)
        def delegated_op(self, k):
            getattr(self, handler)(lambda x: op_func(x, k))
        setattr(cls, '__{}__'.format(op), delegated_op)

    def add_reflected_op_method(op, cls):
        op_func = getattr(operator, op)
        def delegated_op(self, k):
            getattr(self, handler)(lambda x: op_func(k, x))
        setattr(cls, '__r{}__'.format(op), delegated_op)

    def decorator(cls):
        for op in numeric_ops:
            add_op_method(op, cls)
            add_reflected_op_method(op, cls) # reverted operation
            add_op_method('i' + op, cls)     # in-place operation
        return cls

    return decorator

现在装饰你的类:

@delegated_arithmetic('_update')
class Foo:
    # ... other methods ...
    def _update(self, f):
        # ... returns a new Foo() object based on transforming
        #     one or more data members with a function f()

装饰器采用您想将调用委托(delegate)给的名称,以使其更通用一些。

演示:

>>> @delegated_arithmetic('_update')
... class Foo(object):
...     def _update(self, f):
...         print 'Update called with {}'.format(f)
...         print f(10)
... 
>>> foo = Foo()
>>> foo + 10
Update called with <function <lambda> at 0x107086410>
20
>>> foo - 10
Update called with <function <lambda> at 0x107086410>
0
>>> 10 + foo
Update called with <function <lambda> at 0x107086410>
20
>>> 10 - foo
Update called with <function <lambda> at 0x107086410>
0

关于python:概括委托(delegate)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16698850/

相关文章:

python - 如何在 Python3 文件中打印 __repr__? (不在 shell 中)

php - 通过 __get() 通过引用返回 null

php - 如何实现_isset魔术方法?

python - 我正在尝试使用 python 实现 strassen 的算法,但出现错误

python - 使用多个数据框创建 pandas 数据框

python - 如何让 Python 2 的 __getitem__ 在一个类上工作?

python - python 中是否有 type() 的魔术方法?

python - 如何从 python 脚本运行并保存 scrapy 状态

python - tensorflow 2.0 : Add image preprocessing step in a saved model

python - 如何使用 Python 对列表中的单词进行笛卡尔积