在Python中,如何在没有is-a关系的情况下共享属性?
我有许多Python类型,它们描述了层次结构,因为它们的属性越来越具体。以下是一个例子,而不是试图用文字来描述它:在Python中,如何在没有is-a关系的情况下共享属性?,python,properties,Python,Properties,我有许多Python类型,它们描述了层次结构,因为它们的属性越来越具体。以下是一个例子,而不是试图用文字来描述它: class A: @property def prop1(self): return self._prop1 class B: @property def prop1(self): return self._prop1 @property def prop2(self): retur
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(boobject,A)
为True
。Python中是否有其他方法可以直接允许这种共享属性而不使用子类?您可以使用装饰器:
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
甚至像这样:
@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
你说“我不想撒谎说C是A,但实际上不是。类型的特征不符合子类化的语义。”对于你模糊的例子,不清楚该怎么做
如果您这样说是因为类A
中有不适用于类C
的附加功能,那么我将从组合中取出类的属性部分,因此您有A
,B
,C
包含AProps
,BProps
,和CProps
,并为属性类提供适当的继承关系
如果没有这样的附加功能,而且属性是按照您所展示的方式构建的,这不仅仅是巧合,那么请在心里将
class A
重命名为class ProvidesProp1
,注意class C
是一个提供prop1
的类,并接受C类
因此为-aa类
您可以使用组合而不是子类化。我想您的意思是,我可以在每个B
中包含A
,然后重新实现B
的属性访问器以从A
实例中提取。这是我想到的另一个解决方案,但它似乎并不比上面所示的实现更紧凑。为什么您真正关心isinstance
返回什么?你真的有很好的理由打电话给isinstance吗?可能没有,但万一有人打电话给你,我不想撒谎说C
是a
,其实它不是。类型的特征不符合子类化的语义。