在Python中实现静态不可变属性的正确方法是什么?
最小示例:
程序模块“家族”具有类Parent
,定义如下:
class Parent():
def __init__(self, type):
self.type = type
父级可以是以下两种字符串类型之一:'mother'
或'father'
。此类的外部用户应该能够在构造时设置类型,并在以后查询parent.type
以获取这两个值之一。此外,“族”模块的其他部分利用Parent
类并依赖于返回的这两个值中的任何一个。因此,对该类型的要求如下:
幼稚的方法可以通过传递字符串来鼓励设置类型:
parent = Parent('mother')
但是这会导致意外的拼写错误(例如Parent('omther')
)。为了防止这种情况,我采用以下方法:
class Parent():
TYPE_MOTHER = 'mother'
TYPE_FATHER = 'father'
TYPES = [TYPE_MOTHER, TYPE_FATHER]
def __init__(self, type):
assert type in self.TYPES, ('Invalid type "%s"' % type)
self.type = type
parent = Parent(Parent.TYPE_MOTHER)
但是,没有什么可以阻止用户根据需要更改这些静态变量,例如:
parent = Parent('mother')
Parent.TYPE_MOTHER = 'burrito'
print(parent.type == Parent.TYPE_MOTHER)
#> False
为了解决这个问题,我考虑使用@staticmethod
和@property
批注:
class Parent():
@property
@staticmethod
def TYPE_MOTHER():
return 'mother'
@property
@staticmethod
def TYPE_FATHER():
return 'father'
这不会阻止用户将字符串传递给构造函数(例如Parent('mother')
),但至少它会阻止他们通过更改父类型可以改变家庭模块。
此方法存在的问题:
对您的问题:
这不是什么类别的。只需继承Mother
和Father
类即可:
class Parent():
def __init__(self, type):
self.type = type
class Mother(Parent):
def __init__(self):
super().__init__('mother')
class Father(Parent):
def __init__(self):
super().__init__('father')
parent = Mother()