python - 附加类作为方法

标签 python

我发现了 Python 的一个有点奇怪的角落我希望能得到一些帮助理解。

假设我有一个类 B,我想将其附加为类 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()

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

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

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()

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

这很有帮助,我的问题是我真的不明白发生了什么。我希望有人能更清楚地解释为什么,如果我只是 setattr 与 B 类,我没有得到 a 实例,但如果我 setattr 使用 B 类的包装器来调用它,然后我确实得到了 a 实例。

最佳答案

FunctionType 实现 __get__因此,当在其定义的类的实例上调用函数时(即作为 bound_method),拥有的实例(此处为 A)被传递给它作为第一个参数。 type 没有那个 __get__,因此它的实例,如您示例中的 B,在调用时不会收到拥有的实例。

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

关于python - 附加类作为方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58175301/

相关文章:

python - 将复杂列表转换为数据框表,其中第一个值作为第二列标题

python - 分离一个csv进行处理

python asyncio - ctrl+c 上的清理事件循环?和 close() 与 stop()

python - 如何在符号表达式中使用 python 数组?

python - 如何在 python 中编写三元条件运算符?

python - 从列表列表python生成值的组合

python - 在 Python 中正确完成

python - 使用 VTK Python API,将多个标量添加到非结构化网格单元

python 相关单词搜索并替换为列表单词

Python 和 Selenium : Unable to locate a specific (href) element to click on