【问题标题】:Using __getattr__ to call child methods for specific type?使用 __getattr__ 调用特定类型的子方法?
【发布时间】:2014-08-23 17:28:14
【问题描述】:

我有一个类的字段是另一个类的实例。

class Field:
    def get(self):
    def set(self, value):
    def delete(self):

class Document:
    def __init__(self):
        self.y = Field()
        self.z = True

我希望能够做的是,当父实例引用其属性时,它会调用子实例的方法。

d = Document()
d.y = 'some value'  # Calls the `set` function of the Field
d.y == 'some value'  # Calls the `get` function of the Field
del d.y  # Calls the `delete` function of the Field

另一个问题是,当字段类型为 Field 时,我只需要这种行为。

我遇到了递归问题,尝试使用__getattr__ 等,类似于:

def __getattr__(self, key):
    if isinstance(getattr(self, key), Field):
        return getattr(self, key).get()
    return getattr(self, key)

递归很明显为什么会发生......但我该如何避免呢?

我已经在 StackOverflow 上看到了一些示例,但我似乎无法弄清楚如何绕过它。

【问题讨论】:

  • 为什么不直接使用描述符?此功能是内置的。
  • 您描述的 Wbat 几乎就是描述符,除了方法名称拼写为 __get____set____delete__,并且描述符被设置为类的属性,而不是实例。我建议您查看有关描述符的一些信息(例如,herehere)。
  • 谢谢!我会试试看,看看效果如何。
  • 附注 idf 你不喜欢使用 Python 3.x,总是让你的类继承自“object”

标签: python python-2.7 recursion getattr


【解决方案1】:

您所描述的或多或少正是 Python 使用 Descriptor 协议访问类的属性的内在方式 -

只需让您的字段类具有__get____set____delete__ 方法,如https://docs.python.org/2/howto/descriptor.html 中所述—— 并确保所有类都将object 作为基类,否则它们继承自旧式类,出于兼容性原因仅存在于 Python 2 中,并且自 Python 2.2 起已弃用(并完全忽略描述符协议)

【讨论】:

  • 对基类的标注很好,我在 2.7。
  • 如果不使用描述符"协议,您的要求可能会变得相当高级。当然可行。
猜你喜欢
  • 2013-12-05
  • 2012-09-21
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 2018-10-08
相关资源
最近更新 更多