9

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__?

2
  • 4
    Although this does not answer your question directly, I suggest reading Ned Batchelders's Facts and myths about Python names and values. I think you will be able to answer your own question after reading it. Commented Aug 20, 2013 at 4:06
  • Thanks everyone, very helpful information. Commented Aug 20, 2013 at 22:09

4 Answers 4

10

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.

Sign up to request clarification or add additional context in comments.

2 Comments

There are valid reasons for changing __name__, though, e.g. when you are creating a class decorator.
Well, if you are returning a completely different class in that decorator, yes. But then you can also construct that class with a type() call, which sets __name__. This is how I've seen it done.
4

__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.

Comments

2

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.