【发布时间】:2020-09-09 18:13:03
【问题描述】:
问题
Python 函数有比较漏洞(见下面的打印输出)。但他们是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 方法,而不是在类的实例上。
-
是的。 Sill,如何使用它们,以及如何应该使用它们。 (我会有点犹豫是否通过
f.__class__.__lt__ = ...更改 FunctionType(如果允许的话!))。 -
很抱歉,我没有得到您想要获得的内容。 > 或 另一个函数是什么意思?
-
@Anwarvic 他试图使用
f < g和g > f来表示函数组合:(f < g)(x) == f(g(x)) -
另外,请注意
f > g > h不会按照您想要的方式工作,因为比较运算符在涉及底层 dunder 方法之前被专门解析。
标签: python python-3.x python-datamodel