简体   繁体   English

将内置方法分配为 class 属性的奇怪行为

[英]Strange behavior assigning builtin methods as class attributes

I encountered a strange behavior that I cannot explain when assigning builtin methods as attributes to a class in Python.在将内置方法作为属性分配给 Python 中的 class 时,我遇到了一个无法解释的奇怪行为。

If I run the following python file:如果我运行以下 python 文件:

class A:
    a = bin
    b = lambda x: bin(x)
    
print(A().a(2))
print(A().b(2))

The call to A().a(2) returns a byte string, but the call to A().b(2) raises:A().a(2)的调用返回一个字节字符串,但对A().b(2)的调用引发:

TypeError: <lambda>() takes 1 positional argument but 2 were given

The signature of the builtin function bin is supposedly bin(number, /) , which seems identical to the signature provided by the lambda above.内置 function bin的签名应该是bin(number, /) ,这似乎与上面 lambda 提供的签名相同。 However, it appears as if A().a is treated as a static method, whereas A().b is treated like an "instance" method (with a self argument implicitly added to the provided lambda).但是,似乎A().a被视为 static 方法,而A().b被视为“实例”方法(将self参数隐式添加到提供的 lambda 中)。 There is an explanation of a similar issue here ( calling a function saved in a class attribute: different behavior with built-in function vs. normal function ), which claims that the reason these two are treated differently is because one is a builtin_function_or_method and the other is a function type.这里有一个类似问题的解释( 调用保存在 class 属性中的 function:内置 function 与正常 function 的不同行为),它声称这两个被不同对待的原因是因为一个是 builtin_function_or_method 和另一个是 function 类型。

However, there is inconsistent behavior even within builtins.但是,即使在内置函数中也存在不一致的行为。

class B(int):
    c = pow
    d = round

print(B(1).d(2))
print(B(1).c(2))

In the case of pow and round , round is treated like an instance method while pow is treated as a static method.powround的情况下, round被视为实例方法,而pow被视为 static 方法。 Both of these builtins are callables capable of taking two unnamed arguments.这两个内置函数都是可调用的,能够接受两个未命名的 arguments。

This behavior exists across all the versions of Python 2.* and 3.* I've tried.这种行为存在于 Python 2.* 和 3.* 我试过的所有版本中。

The answer you've referenced is correct.您引用的答案是正确的。 In the counter-example you gave the two built-in functions are indeed treated the same, that is no bound method object is created:在你给出的反例中,两个内置函数确实被相同对待,即没有创建绑定方法 object:

B(1).d(2) == round(2)  # not round(B(1), 2)
B(1).c(2) == pow(2)  # not pow(B(1), 2)

the issue arises from passing only one argument to pow which takes at least 2, as opposed to round which does only need one问题是由于仅将一个参数传递给至少需要 2 个的pow ,而不是只需要一个的round

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM