【问题标题】:Why don't monkey-patched methods get passed a reference to the instance?为什么猴子修补方法不传递对实例的引用?
【发布时间】:2014-05-29 05:12:39
【问题描述】:

请参阅此示例进行演示:

>>> class M:
       def __init__(self): self.x = 4
>>> sample = M()
>>> def test(self):
        print(self.x)
>>> sample.test = test
>>> sample.test()
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    sample.test()
TypeError: test() missing 1 required positional argument: 'self'

为什么?

【问题讨论】:

    标签: python oop python-3.x self monkeypatching


    【解决方案1】:

    函数与任何其他对象一样是对象,并且无论名称在哪里(即在本地命名空间中或作为对象的属性),在将对象分配给名称时都需要保持一致。

    当您使用def 定义函数时,您将函数绑定到def 之后的名称,而当您执行some_object.f = my_function 之类的赋值时,您还将函数绑定到名称。分配过程中没有任何魔法可以改变函数的性质。

    在类定义过程中有魔法。定义为实例方法的函数(即定义在类定义中的函数)不是简单地作为属性分配给实例,而是使用descriptor 绑定到实例。

    【讨论】:

      【解决方案2】:

      您分配给sample.testtest 方法未绑定到sample 对象。你需要像这样手动绑定它

      import types
      sample.test = types.MethodType(test, sample)
      sample.test()
      # 4
      

      【讨论】:

      • 这种行为是否仅限于 py3k?
      • @BrianCain 不。 Python 2.x 也一样
      • 或者直接使用函数作为描述符:sample.test = test.__get__(sample)。来源链接:func_descr_get
      猜你喜欢
      • 2015-03-23
      • 1970-01-01
      • 2010-10-01
      • 2017-02-12
      • 2022-11-24
      • 2015-11-10
      • 2011-03-20
      • 2021-03-10
      • 1970-01-01
      相关资源
      最近更新 更多