承接上一个问题:Python 如何直接调用类方法的引用?
python 为什么可以直接调用 class method 的引用,而不能直接调用 instance method 的引用?
使用 instance method 的引用不 ok
from typing import Callable
from loguru import logger
class Work:
def run(self, data: str):
logger.debug(data)
method = Work.run
method('哈哈')
报错了:
─➤ python -u "/home/bot/Desktop/ideaboom/011.py"
Traceback (most recent call last):
File "/home/bot/Desktop/ideaboom/011.py", line 17, in <module>
method('哈哈')
TypeError: Work.run() missing 1 required positional argument: 'data'
但是使用 class method 就 ok
from typing import Callable
from loguru import logger
class Reload:
@classmethod
def wait(cls,data:str):
logger.debug(data)
method=Reload.wait
method('哈哈')
一切正常
─➤ python -u "/home/bot/Desktop/ideaboom/011.py"
2022-08-03 00:10:58.491 | DEBUG | __main__:wait:9 - 哈哈
python 的 function 绑定一个类对象之后成为一个 instance method。instance method 通过
__self__
记录绑定的对象,通过__func__
属性记录绑定的函数。调用 instance method 的时候,会把__self__
属性自动插入到参数列表的第一个,然后调用__func__
。instance method 可用通过
类实例.方法
的形式生成。方法需要时定义在类里的,而不是类示例的属性。直接使用类.方法
是不能生成 instance method 的,只能得到原始的函数。@classmethod
是一个 magic 。他是一个 python 内置类,可以使得在得到 instance method 的时候,__self__
上绑定类本身而不是类对象,并且在使用类.方法
的时候也可以完成绑定,得到 instance method 。所以,
Woker.run
需要传第一个参数,因为它是一个普通的函数,不是 instance method。Reload.wait
则不需要传第一个参数,因为它是一个 instance method ,已经绑定了第一个参数。