Вопрос по name-mangling, attributes, underscores, python, private-members – Python «личное» искажение имени и экземпляр против атрибутов класса

6

Я писал декоратор, которому нужен доступ к закрытым переменным, и обнаружил это несоответствие. Кто-нибудь может объяснить это?

(Python 2.5)

Использование именования работает, как ожидается, для атрибутов, определенных в классе:

>>> class Tester(object):
...    __foo = "hi"

>>> t = Tester()
>>> t._Tester__foo
'hi'

Атрибуты экземпляра не работают (и это то, как мы должны делать это правильно?)

>>> class Tester(object):
...     def __init__(self):
...         self.__foo = "hi"

>>> t = Tester()
>>> t._Tester__foo
AttributeError: 'Tester' object has no attribute '_Tester__foo'

Постскриптум Является & quot; атрибутом класса & quot; правильное слово для этого? Они не являются статичными, но если вы сделаете один из них списком или каким-либо другим изменяемым типом, он будет доступен ...

Update

На самом деле, второй пример тоже работает нормально. Это была аппаратная проблема (перезагрузка помогла).

Атрибут класса - правильное слово. И ониalways общий. Изменчивость не имеет значения. Это почти никогда не имеет значения, за исключением вопроса, можете ли вы изменить данный объект. user395760
Скорее оставьте все как есть, поскольку @MartijnPieters прошел весь процесс тестирования этой проблемы во многих тестах Python. jsbueno
Могу ли я обнулить этот вопрос? Или кто-то видит ценность в его сохранении? Я не могу воспроизвести мою оригинальную проблему. Кажется, работает как ожидалось. Rafe

Ваш Ответ

1   ответ
9

not правильный.

Перенос имени происходит во время создания класса; любые функции, которые ссылаются на искаженные имена, также корректируются.

Я не могу воспроизвести ваш пример, по крайней мере, в Python версий 2.4, 2.5, 2.6, 3.1 и 3.2 на Mac:

>>> class Tester(object):
...     def __init__(self):
...         self.__foo = "hi"
... 
>>> Tester()._Tester__foo
'hi'
>>> Tester().__foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Tester' object has no attribute '__foo'

Если вы разберете байт-код функции, то увидите, что имя было искажено:

>>> import dis
>>> dis.dis(Tester.__init__)
  3           0 LOAD_CONST               1 ('hi')
              3 LOAD_FAST                0 (self)
              6 STORE_ATTR               1 (_Tester__foo)
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE        

Я проверилисточник компилятора а такжеall имена проходят через mangler, путь к коду, который остается неизменным, по крайней мере, с 2002 года.

И да, атрибуты класса и атрибуты экземпляра являются правильными терминами. Атрибуты класса всегда разделяются, но присваиваниеto атрибут экземпляра присваивает этому экземпляру. Мутирование списка или других изменяемых объектов отличается от назначения атрибутов.

Вы правы. Я понятия не имею, что там произошло. Я случайно перезагружаю свой компьютер, поэтому мне просто нужно назвать это ИТ-проблемой "Вы пытались выключить и снова включить его?" ;) Rafe
Также работает с 3.2.

Похожие вопросы