Вопрос по python – Как мне динамически создавать свойства в 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, но я хочу иметь контроль над доступом для чтения / записи / удаления (по этой причине я хочу использовать свойство). Спасибо!
@property\ndef something()
эквивалентноsomething = property(something)
, Что эквивалентно действию (в этом случае)self.setattr('a', property(lambda self: self.__dict['a']))
Joel Cornett
__dict
прямо и доверяй им, чтобы не напортачить. Помните, что мы все взрослые люди, согласные на это!
Нед Батчелдер объясняет лучше, чем я могу:
Keep data out of your variable namesThe question reminded me of others I've seen on Stack Overflow or in the #python IRC channel:
How do I see if a variable exists? How do I use a variable as the name of another variable? How do I use a variable as part of a SQL table name?The thing all these have in common is trying to bridge the gap between two domains: the data in your program, and the names of data in your program. Any time this happens, it's a clear sign that you need to move up a level in your data modeling. Instead of 26 lists, you need one dictionary. Instead of N tables, you should have one table, with one more column in it.
__dict
непосредственно это уродливо, особенно с искажением названия, которое будет вовлечено. Небольшой синтаксический сахар для клиентов иногда имеет большое значение, не говоря уже об уровне косвенности, который он обеспечивает, будет способствовать возможным будущим изменениям.
__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))