#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. Отлично, спасибо! Я попробовал, и это работает идеально. Я не знаю, почему я об этом не подумал.