Избавьтесь от Python приватных указывающих префиксов - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть собственный класс, подобный этому:

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» при вызове конструктора. Почему это происходит?

Позже я мог бы добавить логи проверки c к сеттерам.

Также, если у вас есть какие-либо предложения по рефакторингу моего кода, пожалуйста, не оставляйте его в сами.

1 Ответ

0 голосов
/ 18 февраля 2020

Это может быть излишним, но это работает:

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 и создает словарь, удаляющий _ в начале любых имен атрибутов. Затем мы вместо этого сериализуем этот экземпляр класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...