Python继承类方法的一些问题

IFC*_*CZT 5 python class-method

我有这个代码:

from typing import Callable, Any


class Test(classmethod):
    def __init__(self, f: Callable[..., Any]):
        super().__init__(f)

    def __get__(self,*args,**kwargs):
        print(args)  # why out put is (None, <class '__main__.A'>) where form none  why no parameter 123
        # where was it called
        return super().__get__(*args,**kwargs)


class A:
    @Test
    def b(cls,v_b):
        print(cls,v_b)

A.b(123)
Run Code Online (Sandbox Code Playgroud)

为什么输出是(None, <class '__main__.A'>)?它是从哪里来的?None为什么它不是我调用它的参数 123

tri*_*cot 3

当从类中检索该方法__get__时,将调用该方法。与实际调用无关。 bAb

为了说明这一点,请将对 的访问b与实际调用分开b

print("Getting a reference to method A.b")
method = A.b
print("I have a reference to the method now. Let's call it.")
method()
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

print("Getting a reference to method A.b")
method = A.b
print("I have a reference to the method now. Let's call it.")
method()
Run Code Online (Sandbox Code Playgroud)

所以你看,输出 in__get__不显示任何有关你调用的参数的信息是正常的b,因为你还没有进行调用。


输出None, <class '__main__.A'>Python 文档一致__get__

object.__get__(self, instance, owner=None)

调用以获取所有者类的属性(类属性访问)或该类的实例的属性(实例属性访问)。可选的owner参数是所有者类,而instance是通过所有者访问属性的实例,或者当通过所有者None访问属性时。

在您的情况下,您使用它来访问b)的属性( ) - 而不是实例- 因此这解释了参数是并且参数是你的类。AAinstanceNoneownerA


使用 生成的第二个输出print(cls,v_b)将打印<class '__main__.A'>for ,因为这是调用方法(而不是实例方法)cls时发生的情况。再次,从文档中:

当类属性引用(例如C,类 )将生成类方法对象时,它会转换为__self__属性为 的实例方法对象C

这里描述了您的情况,A类在哪里,因此第一个参数(您称为cls)将作为 value 获得A