Как мне динамически создавать свойства в 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, но я хочу иметь контроль над доступом для чтения / записи / удаления (по этой причине я хочу использовать свойство). Спасибо!

 Joel Cornett10 июн. 2012 г., 11:38
@ThiefMaster: я исправляюсь :)
 Joel Cornett10 июн. 2012 г., 11:29
дела@property\ndef something() эквивалентноsomething = property(something), Что эквивалентно действию (в этом случае)self.setattr('a', property(lambda self: self.__dict['a']))
 ThiefMaster♦10 июн. 2012 г., 11:35
@JoelCornett: второе утверждение в вашем комментарии неверно, вам нужно установить его для класса, а не для экземпляра:paste.aeum.net/show/106, Причина этого в том, чтоhow descriptors work: The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in an owner class (the descriptor must be in either the owner’s class dictionary or in the class dictionary for one of its parents).

Ответы на вопрос(2)

__dict прямо и доверяй им, чтобы не напортачить. Помните, что мы все взрослые люди, согласные на это!

Нед Батчелдер объясняет лучше, чем я могу:

Keep data out of your variable names

The 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.

 10 июн. 2012 г., 13:04
Проблема с доступом__dict непосредственно это уродливо, особенно с искажением названия, которое будет вовлечено. Небольшой синтаксический сахар для клиентов иногда имеет большое значение, не говоря уже об уровне косвенности, который он обеспечивает, будет способствовать возможным будущим изменениям.
 10 июн. 2012 г., 12:46
Нед имеет хороший смысл, но здесь есть цель инкапсуляции. Это важно не только для предотвращения ошибок (которые могут совершать и взрослые по обоюдному согласию), но и для удобства. Внутренний код класса, вероятно, имеет веские основания рассматривать словарь как словарь, в то время как код клиента обрабатывает его как набор атрибутов.
Решение Вопроса

__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))
 10 июн. 2012 г., 12:56
+1: также заботится о СУХОЙ проблеме.
 08 янв. 2016 г., 01:33
Это прекрасно!
 10 мая 2016 г., 13:32
Спасибо! Очень просто и легко понять.

Ваш ответ на вопрос