python Как создать приватные переменные класса с помощью setattr или exec?

Я только что столкнулся с ситуацией, когда псевдоприватные имена членов класса не искажаются при использовании setattr или exec.

In [1]: class T:
   ...:     def __init__(self, **kwargs):
   ...:         self.__x = 1
   ...:         for k, v in kwargs.items():
   ...:             setattr(self, "__%s" % k, v)
   ...:         
In [2]: T(y=2).__dict__
Out[2]: {'_T__x': 1, '__y': 2}

Я пробовал exec("self.__%s = %s" % (k, v)) с тем же результатом:

In [1]: class T:
   ...:     def __init__(self, **kwargs):
   ...:         self.__x = 1
   ...:         for k, v in kwargs.items():
   ...:             exec("self.__%s = %s" % (k, v))
   ...:         
In [2]: T(z=3).__dict__
Out[2]: {'_T__x': 1, '__z': 3}

Выполнение self.__dict__["_%s__%s" % (self.__class__.__name__, k)] = v сработает, но __dict__ является атрибутом только для чтения.

Есть ли другой способ динамически создавать эти псевдоприватные члены класса (без жесткого кодирования в искажении имен)?


Лучше сформулировать мой вопрос так:

Что делает python "под капотом", когда встречает установленный атрибут с двойным подчеркиванием (self.__x)? Есть ли волшебная функция, которая используется для этого?

8
задан chown 16 October 2011 в 16:08
поделиться