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.Short version
class Foo(object): pass
creates a class and assigns it to local nameFoo
.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.__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.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.