摆脱Python私有指示前缀

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

我有一个这样的自定义类:

import json

class Config:
    def __init__(self):
        self._field1 = None
        self._field2 = None

    @property
    def field1(self):
        return self._field1

    @field1.setter
    def field1(self, value):
        self._field1 = value

    @property
    def field2(self):
        return self._field2

    @field2.setter
    def field2(self, value):
        self._field2 = value

    def validate(self):
        fields = [attribute for attribute in dir(self) if not attribute.startswith('__') and not callable(getattr(self, attribute))]
        for field in fields:
            if getattr(self, field) == None:
                raise AttributeError("You must set all fields, " + str(field) + " is not set")

    def toJSON(self):
        return json.dumps(self, default=lambda o: vars(o), 
            sort_keys=True, indent=4)

您可以看到我尝试对我的类进行JSON序列化,但是它始终在json中包含_前缀(因为vars会返回该前缀)

问题1:如何摆脱它?

问题2:我试图从类中删除_前缀,但是在调用构造函数时,我将收到“错误:调用Python对象时超出了最大递归深度”。为什么会这样?

稍后,我可能会向设置员添加验证逻辑。

此外,如果您对如何重构我的代码有任何建议,也请不要随便保存。

python json python-3.x private
1个回答
0
投票
这可能是矫kill过正,但这有效:

import json class _ConfigSerializable: __dict__ = {} def __init__(self, config): for x, y in config.__dict__.items(): while x.startswith("_"): x = x[1:] self.__dict__[x] = y class Config: def __init__(self): self._field1 = None self._field2 = None @property def field1(self): return self._field1 @field1.setter def field1(self, value): self._field1 = value @property def field2(self): return self._field2 @field2.setter def field2(self, value): self._field2 = value def validate(self): fields = [attribute for attribute in dir(self) if not attribute.startswith('__') and not callable(getattr(self, attribute))] for field in fields: if getattr(self, field) == None: raise AttributeError("You must set all fields, " + str(field) + " is not set") def toJSON(self): s = _ConfigSerializable(self) return json.dumps(s, default=lambda o: vars(o), sort_keys=True, indent=4) print(Config().toJSON())

输出:

{ "field1": null, "field2": null }

基本上,我们创建一个新类,该类接受config实例的属性,并创建一个字典,并在任何属性名称的开头删除_。然后,我们序列化该类实例。
© www.soinside.com 2019 - 2024. All rights reserved.