3

我有许多描述层次结构的 Python 类型,因为它们在属性方面越来越具体。与其试图用语言来描述它,不如举一个例子:

class A:
    @property
    def prop1(self):
        return self._prop1

class B:
    @property
    def prop1(self):
        return self._prop1

    @property
    def prop2(self):
        return self._prop2

class C:
    @property
    def prop1(self):
        return self._prop1

    @property
    def prop2(self):
        return self._prop2

    @property
    def prop3(self):
        return self._prop3

因此,当您查看类列表时,B具有的所有属性A以及一些额外的属性。C具有的所有属性,B然后是一些额外的属性,依此类推。如果可能的话,我想尽量减少上述定义的重复。

一个明显的解决方案是使用继承,创建B一个子类A等等。但是,这些类型的语义不遵循 is-a 关系;我不想isinstance(bObject, A)成为True。Python中是否有另一种方法可以直接允许这种属性共享而不使用子类?

4

2 回答 2

7

您可以使用装饰器:

def has_prop1(cls):
    @property
    def prop1(self):
        return self._prop1

    cls.prop1 = prop1

    return cls

@has_prop1
class A(object):
    pass

合成会是这样的:

@has_prop1
@has_prop2
class B(object):
    pass

甚至像这样:

def has_many_properties(cls):
    return has_prop1(has_prop2(has_prop3(cls)))

@has_many_properties
class C(object):
    pass
于 2012-07-17T16:10:07.030 回答
0

你说“我不想撒谎说 C 是 A 而实际上不是。类型的特征不符合子类化的语义。” 对于您的模糊示例,尚不清楚要走哪条路。

如果您之所以这么说是因为其中有class A不适用于的附加功能class C,那么我将组合地取出该类的属性部分,因此您分别拥有A, B,C包含AProps,BPropsCProps, 并为属性类提供适当的继承关系。

如果没有这样的附加功能,并且属性以您显示的方式构建不仅仅是巧合,那么请在脑海中重命名class Aclass ProvidesProp1,注意class Cis-a 提供的类prop1,并因此接受class Cis-a class A

于 2012-07-17T18:47:40.047 回答