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
这与dunder方法的实现无关,与您试图修改内置函数类型的现有行为有关。您将无法修改基础类,并且将忽略在实例上分配这些属性
您可以将它们用于自己的类,在这些类中,实例之间有一个自然的比较。例如,标准库
fractions.Fraction
类支持这些比较;在Python中实现时,需要使用这些方法啊,啊,啊
这在很大程度上与Python的禅宗格格不入。有一些原因表明它还不能以这种方式工作。Numpy对运营商所做的事情已经在推动它,而且大多数情况下是可以容忍的,因为它们是多么的有用。(另外,正如在评论中指出的,Python对链式关系运算符的特殊处理将使它无法按您希望的方式在非平凡情况下工作。)
您可以做的最简单的事情就是定义一个支持组合的包装器。由于比较运算符的处理,我建议使用
>>
和<<
进行组合相关问题 更多 >
编程相关推荐