1

从另一个类中借用实例方法的实现很简单,但是如何使用类方法呢?

class A:
  def im(self):
    print(self.__class__.__name__)

  @classmethod
  def cm(cls):
    print(cls.__name__)

class B:
  im = A.im
  cm = A.cm # line X
  classmethod(cm)

B().im() # B - OK
B.cm() # A - not what I want

我还尝试将 X 行更改为cm = A.cm.__func__,这导致TypeError: cm() missing 1 required positional argument: 'cls'

4

2 回答 2

4

当您访问时,您将对象作为描述符A.cm调用,这意味着它已经绑定到类。再次打开它:classmethodA

class B:
    cm = classmethod(A.cm.__func__)

.__func__属性使您可以访问原始函数,因此您可以使用新classmethod调用重新包装它。

或者,使用A.__dict__映射来获取实际的类方法本身,绕过描述符调用:

class B:
    cm = A.__dict__['cm']
于 2013-06-27T07:56:58.267 回答
3

你需要:

class B:
  im = A.im
  cm = classmethod(A.cm.__func__)

当你访问A.cm时,生成的类方法已经“知道”它属于 A。如果你想为不同的类重新包装它,你需要用 提取底层函数,__func__然后用 重新包装它classmethod

此外,在您的示例中,该行classmethod(cm)什么也不做,因为您没有将结果分配给任何东西。

于 2013-06-27T07:55:57.803 回答