Что лучше __repr__ для пользовательского класса Python?
-
28-10-2019 - |
Вопрос
Кажется, есть разные способы __repr__
Функция может вернуться.
У меня есть класс InfoObj, в которой хранится несколько вещей, некоторые из которых я не особенно хочу, чтобы пользователи класса установили сами. Я не признаю, что в Python ничего не защищено, и они могут просто погрузиться и установить его, но, кажется, определяет это в __init__
делает это более вероятно, кто -то может увидеть это, и предположить, что это хорошо, просто пройти его.
(Пример: логические, которые устанавливаются функцией проверки, когда он определяет, что объект был полностью заполнен, и значения, которые рассчитываются по другим значениям, когда хранится достаточное количество информации ... например, A = B + C, поэтому один раз A и B устанавливаются, затем C рассчитывается, и объект помечен действительным = TRUE.)
Итак, учитывая все это, что является лучшим способом разработки вывода __ repr__?
bob = InfoObj(Name="Bob")
# Populate bob.
# Output type A:
bob.__repr__()
'<InfoObj object at 0x1b91ca42>'
# Output type B:
bob.__repr__()
'InfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
# Output type C:
bob.__repr__()
'InfoObj.NewInfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
... смысл типа C - не с радостью взять все вещи, которые бы я установил «приватный» в C ++ в качестве аргументов для конструктора, и заставить товарищей по команде, используя класс, устанавливая его, используя интерфейсные функции, даже если это больше работы для них. В этом случае я бы определил конструктор, который не принимает определенные вещи, и отдельную функцию, которая немного сложнее заметить, для целей __repr__
Если это имеет какое -либо значение, я планирую сохранить эти объекты Python в базе данных, используя их __repr__
вывод и извлечь их с помощью eval()
, по крайней мере, если я не приду к лучшему. Следствием того, как товарищ по команде создает полный объект вручную вместо того, чтобы просматривать правильные функции интерфейса, является просто то, что один тип поиска информации может быть нестабильным, пока кто -то не выяснит, что он сделал.
Решение
А __repr__
Метод предназначен для создания наиболее полезного вывода для разработчика, а не для эндоусатора, поэтому только вы действительно можете ответить на этот вопрос. Тем не менее, я бы обычно использовал вариант B. Вариант A не очень полезен, и вариант C не нужен доставки - вы не знаете, как ваш модуль импортируется в любом случае. Другие могут предпочесть вариант C.
Однако, если вы хотите хранить объекты Python, является базой данных, используйте pickle
.
import pickle
bob = InfoObj(Name="Bob")
> pickle.dumps(bob)
b'...some bytestring representation of Bob...'
> pickle.loads(pickle.dumps(bob))
Bob(...)
Если вы используете более старый Python (pre-3.x), обратите внимание, что cPickle
быстрее, но pickle
более расширяется. Pickle будет работать на некоторых ваших классах без какой -либо конфигурации, но для более сложных объектов вы можете написать пользовательские пьетки.