Python静态不可变属性

问题描述 投票:1回答:1

在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')),但至少它会阻止他们通过更改父类型可以改变家庭模块。


此方法存在的问题:

  • 这很丑,用4行代码代替了1行
  • 感觉很hacky(可能是由于我在使用其他语言的语言支持的私有静态变量方面的经验)
  • 我的IDE的linter不喜欢它,因为没有'self'参数(即使提供了它)

对您的问题:

  • 这是Pythonic吗?
  • 有更好的方法吗?
  • 您能否建议一种模式,以实现这种不变性,同时还强制用户仅使用我希望它们使用的变量,从而防止它们将原始字符串传递给构造函数?
python design-patterns interface immutability static-variables
1个回答
0
投票

这不是什么类别的。只需继承MotherFather类即可:

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()
© www.soinside.com 2019 - 2024. All rights reserved.