python - python函数比较dunders的使用
问题描述
问题
Python 函数有比较 dunders(见下面的打印输出)。但他们是NotImplemented
。很公平。但是它们的预期用途是什么,如何使用它们?当我分配一个可调用对象时func.__gt__
,我没有看到它被调用func < other_func
。
示例代码
我可以看到使用与(foo > bar)
等效的函数lambda x: foo(x) > bar(x)
,但同样(并且可以说更有用),它可以用于构造管道。
例如,我们可以有
def composeable(func):
func.__gt__ = lambda g: lambda x: g(f(x))
func.__lt__ = lambda g: lambda x: f(g(x))
return func
可以用作
>>> def composeable(func):
... func.__gt__ = lambda g: lambda x: g(f(x))
... func.__lt__ = lambda g: lambda x: f(g(x))
... return func
...
>>> @composeable
... def f(x):
... return x + 2
...
>>> def g(x):
... return x * 10
...
>>> h = f.__gt__(g)
>>> assert h(3) == 50 # (3 + 2) * 10
>>> h = f.__lt__(g)
>>> assert h(3) == 32 # (3 * 10) + 2
然而,越来越好奇,这行不通:
>>> h = f > g
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'function' and 'function'
注意:可调用NotImplemented
函数 dunders。
__eq__: NotImplemented
__ge__: NotImplemented
__gt__: NotImplemented
__le__: NotImplemented
__lt__: NotImplemented
__ne__: NotImplemented
生成上述打印输出的代码:
from inspect import signature
def f(x): ...
for aname in dir(f):
attr = getattr(f, aname)
if callable(attr):
try:
x = attr(*len(signature(attr).parameters) * [''])
if x is NotImplemented:
print(f"{aname}: NotImplemented")
except Exception as e:
pass
解决方案
您可以做的最简单的事情是定义一个支持组合的包装器。由于比较运算符的处理,我建议使用>>
and<<
进行组合。
# Assumption: the wrapped callable take a single argument
class ComposableCallable:
def __init__(self, func):
self.func = func
def __lshift__(self, other):
@ComposableCallable
def _(x):
return self.func(other.func(x))
return _
def __rshift__(self, other):
@ComposableCallable
def _(x):
return other.func(self.func(x))
return _
def __call__(self, x):
return self.func(x)
@ComposableCallable
def f(x):
return x + 1
@ComposableCallable
def g(x):
return 2 * x
assert (f << g)(3) == 7 # 2*3 + 1 == 7
assert (f >> g)(3) == 8 # (3 + 1) * 2 == 8
推荐阅读
- python - 计算特定段中的比例加权值:使其更 Pythonic
- vba - 将公式从一列复制到可变数量的列
- javascript - 如何将 Jqgrid 行数据作为数组获取
- javascript - 如何在 react-select v2 中创建 optgroup?
- javascript - 来自反应组件的 OnClick 相关功能不起作用
- c# - 每天午夜进行选择的 ASP.NET 例程
- domain-driven-design - 学习 DDD 和 CQRS
- c# - 如何在 SpecFlow 中更好地使用 ScenarioContext 以实现可维护性
- java - 如何从图像视图中裁剪图像的屏幕可见部分并将其存储?
- css - 滑块图像加载时间和显示问题