在为测试自动化开发代码时,我经常将SUT中的响应从XML / JSON /转换为Python对象模型,以便以后更容易使用它。
由于客户端不应该更改存储在对象模型中的信息,因此将所有实例属性设置为只读是有意义的。
对于简单的情况,这可以通过使用collections模块中的namedtuple来实现。但在大多数情况下,一个简单的命名小组不会做。
我知道最可能是pythonic的方式是使用属性:
class MyReadOnlyClass(object):
def __init__(self, a):
self.__a = a
@property
def a(self):
return self.__a
如果我只处理一些属性,这很好,但很快就会变得很长。
所以我想知道是否还有其他可接受的方法?我想出的是:
MODE_RO = "ro"
MODE_RW = "rw"
class ReadOnlyBaseClass(object):
__mode = MODE_RW
def __init__(self):
self.__mode = MODE_RO
def __setattr__(self, key, value):
if self.__mode != MODE_RW:
raise AttributeError("May not set attribute")
else:
self.__dict__[key] = value
然后我可以将其子类化并像这样使用它:
class MyObjectModel(ReadOnlyBaseClass):
def __init__(self, a):
self.a = a
super(MyObjectModel, self).__init__()
超级调用之后,无法添加或修改实例属性(......至少可以轻松实现)。
我想到的一个可能的警告是,如果有人要修改__mode属性并将其设置为MODE_RO,则不能创建新实例。但这似乎是可以接受的,因为它明确标记为"私人" (以Pyhon的方式)。
如果您发现此解决方案存在任何问题,或者采用完全不同且更好的方法,我会感兴趣。 或者根本不鼓励这种情况(请解释一下)?