Как динамически создавать свойства в Python?
Предположим, что у меня есть класс:
class Alphabet(object):
__init__(self):
self.__dict = {'a': 1, 'b': 2, ... 'z': 26}
@property
def a(self):
return self.__dict['a']
@property
def b(self):
return self.__dict['b']
...
@property
def z(self)
return self.__dict['z']
Это была бы долгая и громоздкая задача для определения, и она кажется крайне избыточной. Есть ли способ динамически создавать эти свойства? Я знаю, что вы можете динамически создавать атрибуты со встроенным setattr, но я хочу иметь контроль над доступом для чтения/записи/удаления (по этой причине я хочу использовать свойство). Спасибо!
Ответы
Ответ 1
Не используйте свойства, но реализуйте следующие методы:
-
__getattr__(self, name)
-
__setattr__(self, name, value)
-
__delattr__(self, name)
См. http://docs.python.org/reference/datamodel.html#customizing-attribute-access
Ваш метод __getattr__
может выглядеть следующим образом:
def __getattr__(self, name):
try:
return self.__dict[name]
except KeyError:
msg = "'{0}' object has no attribute '{1}'"
raise AttributeError(msg.format(type(self).__name__, name))
Ответ 2
Не делай этого. Просто позвольте потребителям класса на __dict
напрямую и доверяйте им, чтобы не испортить его. Помните, мы все согласны с взрослыми здесь!
Нед Батчелдер объясняет мне лучше, чем я могу:
Вопрос напомнил мне о других, которые я видел при переполнении стека или в #python IRC-канал:
- Как узнать, существует ли переменная?
- Как использовать переменную как имя другой переменной?
- Как использовать переменную как часть имени таблицы SQL?
Все, что у них общего, пытается преодолеть разрыв между два домена: данные в вашей программе и имена данных в вашем программа. Каждый раз, когда это происходит, это явный признак того, что вам нужно повышайте уровень в моделировании данных. Вместо 26 списков вам нужно один словарь. Вместо N таблиц вы должны иметь одну таблицу, с еще один столбец.