在Python Language Reference, Chapter 3 Datamodel中, 为什么“实例方法”列在“可调用类型”下,而“静态方法对象”和“类方法对象”列在“内部类型”下?
可调用类型这些类型可以应用函数调用操作(请参阅调用部分) ...
实例方法 ...
内部类型解释器内部使用的一些类型会向用户公开。他们的定义可能会改变 与未来版本的解释器,但为了完整性,这里提到它们。 ...
静态方法对象 ...
类方法对象 ...
静态和类方法对象不应该是可调用类型吗?
答案 0 :(得分:5)
不,staticmethod
和classmethod
不可调用,no rationale to do so was found。
>>> def foo():
... print("hello")
>>> s = staticmethod(foo)
>>> s()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'staticmethod' object is not callable
它们是通过描述符协议调用的,并且(通常)返回一个可调用的:
>>> s.__get__(foo)()
hello
但是,这不是最常见的形式。通常,在属性访问{... 3}}时会自动调用描述符:
描述符可以通过其方法名称直接调用。例如,
d.__get__(obj)
。或者,更常见的是在属性访问时自动调用描述符。例如,
obj.d
在d
字典中查找obj
。如果d
定义方法__get__()
,则根据下面列出的优先规则调用d.__get__(obj)
。
答案 1 :(得分:3)
staticmethod
个对象不可调用:
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> staticmethod(lambda x: print(x))
<staticmethod object at 0x7f8499f1ebe0>
>>> meth = staticmethod(lambda: print('static method called'))
>>> meth()
Traceback (most recent call last):
然而,他们实现了描述符协议方法__get__
。然后__get__
方法返回一个实际的可调用对象。
File "<stdin>", line 1, in <module>
TypeError: 'staticmethod' object is not callable
>>> meth.__get__(object, object())()
static method called
将staticmethod
对象存储到类属性中,然后查找时,会隐式调用__get__
方法。