2013-08-20 3 views
6

Я пытаюсь понять взаимосвязь между переменной, которой назначен объект класса Python, и атрибутом __name__ для этого объекта класса. Например:Имя переменной класса Python vs __name__

In [1]: class Foo(object): 
    ...:  pass 
    ...: 

In [2]: Foo.__name__ = 'Bar' 

In [3]: Foo.__name__ 
Out[3]: 'Bar' 

In [4]: Foo 
Out[4]: __main__.Bar 

In [5]: Bar 
--------------------------------------------------------------------------- 
NameError         Traceback (most recent call last) 
<ipython-input-5-962d3beb4fd6> in <module>() 
----> 1 Bar 

NameError: name 'Bar' is not defined 

Так что, похоже, как я изменил атрибут класса __name__, но я не могу обратиться к нему с этим именем. Я знаю, что это немного общее, но может ли кто-нибудь объяснить связь между Foo и Foo.__name__?

+4

Хотя это не отвечает на ваш вопрос напрямую, я предлагаю прочитать [Факты и мифы о именах и значениях Python] (http://nedbatchelder.com/text/names.html). Я думаю, вы сможете ответить на свой вопрос после прочтения. –

+0

Спасибо всем, очень полезная информация. – ACV

ответ

9

Это просто. Нет никакой связи.

При создании класса создается локальная переменная с именем, которое вы использовали, указывая на класс, чтобы вы могли его использовать.

Класс также получает атрибут __name__, который содержит имя этой переменной, потому что это удобно в некоторых случаях, например, при травлении.

Вы можете установить локальную переменную на что-то еще или изменить переменную __name__, но тогда такие вещи, как травление, не будут работать, поэтому не делайте этого.

+0

Имеются веские причины для изменения '__name__', хотя, например, когда вы создаете декоратор класса. – nneonneo

+0

Ну, если вы возвращаете совершенно другой класс в этом декораторе, да. Но тогда вы также можете построить этот класс с вызовом 'type()', который устанавливает '__name__'. Вот как я это видел. –

3

__name__ - это просто самоидентификация, чтобы узнать, какой тип экземпляра на самом деле есть.

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

Они оба назначены во время определения класса.

Он работает одинаково с функциями: если вы их def, они присваиваются данному имени и получают соответствующий атрибут __name__.

OTOH, если у вас есть функция lambda, он получает атрибут __name__<lambda>, так как он не знает имя, которому он назначен.

1

Короткая версия

class Foo(object): pass создает класс и присваивает его локальное имя Foo.

Foo.__name__ = 'Bar' присваивает новое значение атрибуту __name__. Объем приложения не изменяется.

Длинная версия

Класс оператор создает класс и присваивает имя, указанное в локальной области видимости. При создании класса Python сообщает классу имя, с которым оно было создано, назначив его атрибуту класса __name__.

Присвоение атрибуту класса не вводит имя в локальную область. Поэтому любые изменения атрибутов (например, __name__) не влияют на область охвата.

0

Вам нужно иметь в виду, что в python класс - это просто объект, как любой другой. Было бы нецелесообразно, чтобы объект содержал атрибут, который был связан с переменной, которая ссылается на объект, потому что может быть любое количество имен переменных, относящихся к нему.Каждый раз, когда вы пишете задание (Bar = Foo) или передаете объект функции, у вас есть новая ссылка. Естественно, все объекты должны быть независимы от того, как они ссылаются.

__name__ - это просто часть информации, прикрепленная к объекту класса, которая, как оказалось, совпадает с именем переменной, изначально назначенной.

Смежные вопросы