python - 在 Python 中覆盖字段的方法

标签 python oop overwrite

我有一个自定义类,我在第二个类中实例化两次:

[编辑:旧代码并没有真正捕获我的问题是什么,我正在重写以使其更清晰。 Foo 将通过使用回调函数来处理网络事件(并且我需要多个连接,因此 Bar 将有多个 Foo 字段并且不能只是继承)。在 Bar 类中,我想覆盖回调以执行不同的操作。在 Foo 中重写 callb 是行不通的,因为我在其他实例中确实继承了它]

class Foo(object):
    def __init__(self, x):
        self._x = x
        #When an event happens, call callb()
        self.on_certain_event(callback=callb)

    def callb(self):
        print self._x

    def run(self):
        waitForEventsInfinitely() #

class Bar(object):
    def __init__(self):
        self._foo = Foo(5)
        #OVERWRITE THE EXISTING CALLBACK METHOD IN THE Foo CLASS!
        self._foo.callb = self.callb

    def callb(self):
        print self._x * 10

    def run(self):
        waitForEventsInfinitely() # Not going to actually write t

f = Foo(2)
f.run()
b = Bar()
b.run()

[当在 Foo 中调用 run() 时,它可以正常工作。但是,我无法从 Bar 覆盖 Foo 的 callb 方法 - Foo 应该引用的 self._x 正在尝试从 Bar 调用]

但是,在运行代码时,我收到错误“Bar has no attribute '_x'”,而不是我期望的值 50。显然,Bar 测试中的 self 仍然指的是 Bar,而不是实际上的 Foo调用该方法。我本以为它是 Bar 中的内部 Foo self._foo 字段。

我怀疑我的问题与名称修改有关,但是当我的自身字段的方法被覆盖时,我无法找到描述性来源。大多数示例似乎是当我从不同的类继承时。

最佳答案

关于 Python 中的类如何工作的简短类(class):存储在类对象上的任何函数(“方法”)都会由 descriptor 自动获取。 (描述如何从对象获取属性)将方法绑定(bind)到用于获取它的类或实例。

例如:

Foo.test 

是 Foo 类的未绑定(bind)方法:这是由 Foo 上的描述符创建的对象,它知道它是从类对象中获取的

Foo().test 

是 Foo 类实例的绑定(bind)方法:此方法存储用于获取函数的 Foo 实例。当您调用结果对象时,此实例会自 Action 为第一个参数传递,这就是您在定义方法时将 self 编写为第一个参数的原因。

所以,你想做的是:

  1. Bar 类获取原始函数test(不通过描述符)
  2. 将此函数绑定(bind)到 Foo 的实例
  3. 将此函数存储在 foo 实例上

所以,这就是你的做法:

import types 

class Bar(object):
    def __init__(self):
        self._foo = Foo(5)

        raw_function = Bar.test_Bar.__func__                        # 1)
        bound_to_foo = types.MethodType(raw_function, self._foo)    # 2)    
        self._foo.test = bound_to_foo                               # 3)

    def test(self):
        print self._x * 10

参见this question有关描述符的更多详细信息。

关于python - 在 Python 中覆盖字段的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15889928/

相关文章:

oop - 你应该使用 protected 成员变量吗?

c# - 接口(interface)属性名称因类而异

Python:用更少的变量写一个新列表

bash - 使命令的输出显示在单行上

python - 如何将 pandas 中的加速度计数据插入固定采样率?

python - 从同一网络上的其他设备连接到 Flask 服务器

python - 如何使用 pandas 读取列中包含空格的空格分隔文件?

java - 在 Eclipse 中分析 Java OO 代码

mysql - 在不存在的地方插入——无主键

python - 同时运行具有两个不同参数的同一脚本