Python - 为什么我可以用实例调用类方法?

Ste*_*ves 9 python inheritance class-method python-2.7

Python的新手并且已经完成了一些阅读,我在自定义类类方法而不是实例方法中创建了一些方法.

所以我测试了我的代码但是我没有改变一些方法调用来调用类而不是实例中的方法,但它们仍然有效:

class myClass:
   @classmethod:
   def foo(cls):
      print 'Class method foo called with %s.'%(cls)

   def bar(self):
      print 'Instance method bar called with %s.'%(self)

myClass.foo()
thing = myClass()
thing.foo()
thing.bar()
Run Code Online (Sandbox Code Playgroud)

这会产生:

class method foo called with __main__.myClass.
class method foo called with __main__.myClass.
instance method bar called with <__main__.myClass instance at 0x389ba4>.
Run Code Online (Sandbox Code Playgroud)

所以我想知道为什么我可以在实例(thing.foo)上调用类方法(foo),(虽然它是传递给方法的类)?这有点道理,因为'thing'是'myClass',但是我期待Python给出一个错误,说'foo是一个类方法并且无法在实例上调用'.

这只是继承的预期后果,'thing'对象从其超类继承foo方法吗?

如果我尝试通过类调用实例方法:

myClass.bar()
Run Code Online (Sandbox Code Playgroud)

然后我得到:

TypeError: unbound method bar() must be called with myClass instance...
Run Code Online (Sandbox Code Playgroud)

这很有道理.

Joh*_*ohn 9

你可以在一个实例上调用它,因为它@classmethod是一个装饰器(它将一个函数作为参数并返回一个新函数).

以下是Python 文档中的一些相关信息

它可以在类(例如Cf())或实例(例如C().f())上调用.除了类之外,该实例被忽略.如果为派生类调用类方法,则派生类对象将作为隐含的第一个参数传递.

还有相当一个良好的SO讨论@classmethod 在这里.

  • “你可以在一个实例上调用它,因为@classmethod 是一个装饰器”——我不遵循这个逻辑。 (2认同)