【问题标题】:How do I concatenate objects stored in an inheritance chain in Python?如何连接存储在 Python 中的继承链中的对象?
【发布时间】:2014-03-23 20:52:29
【问题描述】:

我正在实现一个用户界面。许多对象向用户界面公开各种属性。它们每个都有一个对象“ExposedProperties”,其中包含一个公开属性列表(以及它们的类型、它们应该如何显示、输入应该如何验证等)。这个 ExposedProperties 对象为每个类计算一次。

我想获得一个对象的所有公开属性的串联。一种方法是让每个对象将其“ExposedProperties”传递到__init__ 中的继承链上,并让每个超类将其与自己的 ExposedProperties 连接起来。基类将在对象上设置连接的 ExposedProperties

另一种方法是等到从一个对象请求所有公开的属性。然后,扫描mro 中的每个类 以查找exposed_properties 属性的基类方法在那时将它们连接起来。

在 Python 中连接存储在继承链中的这些对象的最 Pythonic 方式是什么?

【问题讨论】:

  • 不使用super?
  • 对象的公开属性集是由其类决定的,还是同一类的不同实例可以公开不同的属性?您的描述听起来好像是前者,但并不完全清楚。
  • @IgnacioVazquez-Abrams:我错过了一个明显的解决方案吗?
  • 调用父类的方法,将新元素添加到返回列表中。
  • 我明白了。但这应该很容易解决。

标签: python inheritance method-resolution-order


【解决方案1】:

由于公开的属性是类属性,因此在创建类时构造所需的列表(类的公开属性及其祖先的属性)是有意义的,您可以为此使用元类。 (编辑:我看到在 cmets 中提出了同样的建议。)

这是一个这样做的例子:

class ExposedMeta(type):

    def __init__(cls, name, bases, attrs):
        if not "exposed_properties" in attrs:
            cls.exposed_properties = []
        all_props = set(cls.exposed_properties)
        for base in bases:
            all_props.update(getattr(base, "all_exposed_properties", []))
        cls.all_exposed_properties = list(all_props)
        super(ExposedMeta, cls).__init__(name, bases, attrs)

class A(object):
    __metaclass__ = ExposedMeta
    exposed_properties = ['A1', 'A2']

class B(A):
    exposed_properties = ['B']

class C(A):
    pass

class D(object):
    __metaclass__ = ExposedMeta
    exposed_properties = ['D']

class E(B, D):
    exposed_properties = ['E1', 'E2']

for cls in [A, B, C, D, E]:
    print "Class %s, exposed: %s, all exposed: %s" % (cls.__name__, cls.exposed_properties, cls.all_exposed_properties)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2011-08-24
    • 1970-01-01
    相关资源
    最近更新 更多