将类作为方法附加

Bil*_*rin 5 python

我发现了Python的一个奇怪的角落,希望能对理解有所帮助。

假设我有一个B要附加的类作为class的方法A。我可以:

class A:
  def __init__(self):
    print("a self is %s " % self)

class B:
  def __init__(self):
    print("b self is %s " % self)

setattr(A, "B", B)

a = A()
a.B()
Run Code Online (Sandbox Code Playgroud)

当我调用时a.B(),在中B.__init__我获得了self一个新的B实例的对象。

现在假设我想aB构造函数中捕获实例的实际值。我发现您可以使用包装函数来做到这一点:

class A:
  def __init__(self):
    print("a self is %s " % self)

class B:
  def __init__(self, a_instance):
    print("b self is %s a_instance is %s " % (self, a_instance))

def _(*args, **kwargs):
  return B(*args, **kwargs)
setattr(A, "B", _)

a = A()
a.B()
Run Code Online (Sandbox Code Playgroud)

使用包装函数,a_instance将与a对象的实际实例引用一起传递。

知道这很有帮助,我的问题是我真的不明白发生了什么。我希望有人能提供一个更清楚的解释,说明为什么如果我只是setattr使用B类,那么就不会得到该a实例,但是如果我setattr在只调用它的B类周围有一个包装器,那么我确实会得到该a实例。

ask*_*oni 2

FunctionType实现__get__这样,当在定义了该函数的类的实例上调用函数时(即作为 a bound_method),拥有的实例(A此处)将作为第一个参数传递给它。type没有那个__get__,所以它的实例,就像B你的例子一样,在调用时不会收到拥有的实例。

@staticmethod在实际代码中几乎总是一个错误,但您可以在函数中使用它来模拟此处类的行为以达到演示目的。