为什么可以直接调用类方法的引用,而不能直接调用实例方法的引用?

承接上一个问题: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 - 哈哈
阅读 1.5k
1 个回答

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 ,已经绑定了第一个参数。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题