python函数比较dunders的使用 问题:
Python函数具有比较dunders(请参见下面的打印输出)。但是它们没有实现。很公平。但是它们的预期用途是什么,人们如何使用它们呢?当我将一个可调用函数指定给python函数比较dunders的使用 问题:,python,python-3.x,python-datamodel,Python,Python 3.x,Python Datamodel,Python函数具有比较dunders(请参见下面的打印输出)。但是它们没有实现。很公平。但是它们的预期用途是什么,人们如何使用它们呢?当我将一个可调用函数指定给func.\uuu gt\uuuu时,我看不到在执行funcbar)是一个相当于lambda x:foo(x)>bar(x)的函数,但同样(也可以说更有用),它可以用于构建管道 例如,我们可以 def可组合(func): 函数=λg:λx:g(f(x)) 函数=λg:λx:f(g(x)) 返回函数 可以用作 def可组合(func):
func.\uuu gt\uuuu
时,我看不到在执行func
时调用它
示例代码
我可以看到使用(foo>bar)
是一个相当于lambda x:foo(x)>bar(x)
的函数,但同样(也可以说更有用),它可以用于构建管道
例如,我们可以
def可组合(func):
函数=λg:λx:g(f(x))
函数=λg:λx:f(g(x))
返回函数
可以用作
def可组合(func):
... 函数=λg:λx:g(f(x))
... 函数=λg:λx:f(g(x))
... 返回函数
...
>>>@composeable
... def f(x):
... 返回x+2
...
>>>def g(x):
... 返回x*10
...
>>>h=f.uu gt_uu(g)
>>>断言h(3)==50#(3+2)*10
>>>h=f.。\uuu lt\uuu(g)
>>>断言h(3)==32#(3*10)+2
然而,好奇者和好奇者,这是行不通的:
>h=f>g
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:“function”和“function”的实例之间不支持“>”
注意:可调用的NotImplemented
函数dunders。
生成上述打印输出的代码:
来自检查导入签名
定义f(x):。。。
对于目录中的aname(f):
attr=getattr(f,aname)
如果可调用(attr):
尝试:
x=attr(*len(签名(attr).参数)*['')
如果未实现x:
打印(f“{aname}:未实现”)
例外情况除外,如e:
通过
然而,好奇者和好奇者,这是行不通的:
这与dunder方法的实现无关,与您试图修改内置函数类型的现有行为有关。您将无法修改基础类,并且将忽略在实例上分配这些属性
如何使用它们,应该如何使用它们
您可以将它们用于自己的类,在这些类中,实例之间有一个自然的比较。例如,标准库fracts.Fraction
类支持这些比较;在Python中实现时,需要使用这些方法
它可以用来建造一条管道
啊,啊,啊
这在很大程度上与Python的禅宗格格不入。有一些原因表明它还不能以这种方式工作。Numpy对运营商所做的事情已经在推动它,而且大多数情况下是可以容忍的,因为它们是多么的有用。(另外,正如在评论中指出的,Python对链式关系运算符的特殊处理将使其无法按您希望的方式在非平凡情况下工作。)您可以做的最简单的事情是定义一个支持组合的包装器。由于比较运算符的处理,我建议使用
>
和Dunder方法来查找类,而不是类的实例。True。窗台,如何使用,应该如何使用。(如果允许的话,我会有点犹豫是否通过执行f.\uuu class\uuuu.\uu lt\uuuuu=…
)来更改函数类型。很抱歉,我没有得到您想要的结果。>或<运算符如何与函数一起使用。比如,让一个函数>另一个函数意味着什么?@Anwarvic他试图用f
和g>f
来表示函数组合:(f
另外,请注意f>g>h
不会按你想要的方式工作,由于比较运算符是在涉及底层dunder方法之前专门解析的,所以管道没有什么特别的问题。函数组合将是一个奇妙的特性,但主要的反对意见是Python函数过于笼统,无法支持单一的组合概念。我的反对意见主要是以这种方式拼写组合操作。同样,我的问题不是关于管道。这只是一个例子。但我肯定被aaaaugh反应和许多pythonistas将其视为法则而不是美丽的反思邀请的倾向所逗乐。我的反思使我得出结论,在我的上下文中,这样的应做和不应做更多的是让代码镜像思想尽可能简单和优雅。我+1代码,因为它是一个优雅的解决方案,使操作员实现组合。但作文只是一个例子,不是问题(事实上,让我想到这一点的实际问题是不同的,但作文更容易解释)。问题是(1)它们的预期用途是什么(如果有),以及(2)如何使用它们(简单地说,dunders使用类,而您不能将函数子类化)。如果一段时间后我的实际问题没有得到任何答案,我会接受你的回答,以奖励我的努力,而不仅仅是放弃提问。我不确定我是否理解你的问题<代码>\uuugt\uuuu
和\uuult\uuuu
以便您可以自定义新类的实例之间的比较方式。这里的问题很简单,就是你不能修改现有的内置类。不知道该怎么说。也许“如果可能的话,我们应该如何使用函数的比较dunders”。在这一点上,答案很可能是您不能使用它们,它们只是对象
的残存特征。显然,我们可以委托给一个函数来使用这些dunder,但是当基类已经包含这些dunder时,这样做似乎很奇怪。
__eq__: NotImplemented
__ge__: NotImplemented
__gt__: NotImplemented
__le__: NotImplemented
__lt__: NotImplemented
__ne__: NotImplemented
# 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