简体   繁体   中英

Python class variable name vs __name__

I'm trying to understand the relationship between the variable a Python class object is assigned to and the __name__ attribute for that class object. For example:

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

So it seems like I have changed the __name__ attribute of the class but I can't refer to it by that name. I know this is a bit general but could someone explain the relationship between Foo and Foo.__name__ ?

It's simple. There is no relationship at all.

When you create a class a local variable is created with name you used, pointing at the class so you can use it.

The class also gets an attribute __name__ that contains the name of that variable, because that's handy in certain cases, like pickling.

You can set the local variable to something else, or change the __name__ variable, but then things like pickling won't work, so don't do that.

__name__ is mere self-identification, in oder to know what type an instance of it really is.

The other thing is the way it can be accessed with. That can vary if you re-assign it.

They both are assigned at the time you define the class.

It works the same way with functions: if you def them, they get assigned to the given name and they get the respective __name__ attribute.

OTOH, if you have a lambda function, it gets a __name__ attribute of <lambda> , because it doesn't know the name it gets assigned to.

Short version

class Foo(object): pass creates a class and assigns it to local name Foo .

Foo.__name__ = 'Bar' assigns a new value to attribute __name__ . The enclosing scope is not affected.

Long version

The class statement creates a class and assigns to the name provided in the local scope. When creating a class Python tells the class the name it was created with by assigning it to the class's __name__ attribute.

Assigning to a class's attribute does not introduce a name into the local scope. Therefore any changes to attributes (such as __name__ ) do not affect the enclosing scope.

You need to keep in mind that in python a class is just an object like any other. It wouldn't make sense for an object to contain an attribute that was linked to a variable that refers to the object, because there could be any number of variable names referring to it. Any time you write an assignment ( Bar = Foo ) or pass the object to a function, you have a new reference. Naturally all objects must be independent of how they are referenced.

__name__ is simply a piece of information attached to the class object, which happens to be the same as the variable name it's initially assigned to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM