You are calling the method with a class, not an object. You need to call it like this:
B().run()
Don't confuse between B
and B()
. One is the instance of B
's metaclass, i.e. a class while the second one is an instance of class B
. Since the method is not declared as a classmethod
, you need an instance of class B
to call it.
Your second code snippet works because in doing A.__init__(A)
, you basically add a class attribute A.var = 15
. When you call B.run(B)
, you basically do A.method(A)
, which simply sets A.var = 0
(which you set as 15 before). You are mixing up classes with instances here, but it still works anyway since in the end, both are essentially objects.
For example, from here
>>> class A:
... def f(self):
... print(1)
>>> A().f
<bound method A.f of <__main__.A object at 0x10b641b50>>
>>> A.f
<function A.f at 0x10b759c10>
The first case clearly shows that it is a bound method to A
's instance that doesn’t need an argument when called with A()
, while in the second case, A.f
is not treated as a method but as a function, which would need an argument in order to be invoked. So you can call it in any way like a plain function accepting one absolute argument (well as long as you don’t do something like print(self.some_attribute)
or self.some_attribute = some_val
inside):
>>> A.f(123123)
1
>>> A.f(33234)
1
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…