Возврат словарного представления объекта, когда атрибуты класса являются частными (Python)

#python #python-3.x #oop

#python #python-3.x #ооп

Вопрос:

Я пытаюсь сгенерировать словарь из объекта на Python. Я использовал object.__dict__ , который работает, когда для атрибутов класса не задано значение private. Однако, когда я устанавливаю для атрибутов значение private, ключи словаря меняются с 'attribute' на '_ClassName__attribute'

Мне просто интересно, есть ли встроенная функция для сохранения имени атрибута как простого 'length' (чтобы привести пример), или мне придется сделать что-то еще.

 class Rectangle():
    def __init__(self,length,breadth):
        self.__length = length
        self.__breadth = breadth

    def get_length(self):
        return self.__length

    def get_breadth(self):
        return self.__breadth

r = Rectangle(2,4)
print(r.__dict__)
  

Вывод:

 {'_Rectangle__length': 2, '_Rectangle__breadth': 4}
  

Желаемый результат:

 {'length': 2, 'breadth': 4}
  

РЕДАКТИРОВАТЬ: следует отметить, что мой код немного сложнее, чем этот, и из-за наследования некоторые из моих словарей могут выглядеть примерно так:

 {'_Rectangle__length' : 2, '_Circle__radius' : 5, '_Square__height' : 9}
  

Таким образом, если нет встроенной функции для простого выполнения того, что я ищу, мне может потребоваться удалить все, вплоть __ до всех ключей. Я уже пробовал это, но возникли проблемы с невозможностью обновления словаря во время итерации. Любые предложения будут оценены.

Комментарии:

1. Просто обратите внимание, что они не являются частными . Они просто искажаются, чтобы избежать случайного затенения атрибутами в дочернем классе. Я бы настоятельно рекомендовал не использовать __ имена атрибутов с префиксом, если у вас нет веских оснований для этого; не используйте их просто по умолчанию, потому что частные атрибуты являются нормой в языках, которые имеют модификаторы видимости.

2. Кроме того, вы не должны использовать __dict__ непосредственно вне метода экземпляра, и вы пытаетесь избежать этого без уважительной причины внутри метода.

3. Спасибо. Есть ли причина, по которой я не должен его использовать? Причина этого заключается в том, что в моем реальном коде я сохраняю все значения атрибутов в формате CSV для каждого объекта, созданного с помощью DictWriter. Поэтому преобразование в словарь таким способом было удобным. И да, я могу просто удалить в __ конечном итоге.

4. Это деталь реализации, на самом деле не часть интерфейса вашего класса. Фактически, если вы используете атрибут __slots__ class, ваши экземпляры не будут иметь __dict__ атрибута.

Ответ №1:

Дизайн Pythonic будет

 class Rectangle:
    def __init__(self, length, breadth):
        self._length = length
        self._breadth = breadth

    @property
    def length(self):
        return self._length

    @property
    def breadth(self):
        return self._breadth

    def to_dict(self):
        return {'length': self._length, 'breadth': self._breadth}

r = Rectangle(2, 4)
print(r.to_dict())
  

Используйте _ имена с префиксом для указания атрибутов, которые не должны использоваться напрямую, и используйте property для предоставления доступа только для чтения к таким атрибутам. Определите метод, который dict явно выдает желаемое, а не пытается повторно __dict__ использовать напрямую.

Комментарии:

1. Отлично, спасибо! Я попробовал, и это работает идеально. Я не знаю, почему я об этом не подумал.