Different classes created by type with the same name in Python?

I played with metaclasses in Python and found something very interesting. I can create two classes with the same name, but in reality they are different objects. Cm:

>>> def create_class(**data): ... return type('MyClass', (object,), data) ... >>> A = create_class(x=1, y=2) >>> B = create_class(x=1, y=2) >>> A <class '__main__.MyClass'> >>> B <class '__main__.MyClass'> >>> A == B False >>> a = A() >>> b = B() >>> type(a) <class '__main__.MyClass'> >>> type(b) <class '__main__.MyClass'> >>> type(a) == type(b) False 

I thought the names in the namespace should be unique. Is not it?

+4
source share
2 answers

Names in the namespace are unique, but this has nothing to do with your situation here. Basically there are two different things: "names" and __name__ s. "Name" is a variable in the namespace. A __name__ is just an attribute of a class whose value is "what the class calls itself."

MyClass code above has the names __name__ and A and B MyClass not a name in the __main__ namespace. The "Class __main__.MyClass " that you see is an attribute of the __name__ class, not the actual variable in the namespace. Typically, the __name__ class will be equal to the name with which you define it, but if you create the class programmatically by calling type , like you, it will still have __name__ , but will not necessarily be available through any name in the namespace.

Here is a simple example of the difference:

 >>> A = type('MyClass', (object,), {}) >>> MyClass Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> MyClass NameError: name 'MyClass' is not defined 

Just passing MyClass to type does not actually create a variable called MyClass . It is these actual variable names that are unique, not the internal concept of his name.

A class is the same as for another class if it is the same object of the class. Even if they have the same __name__ attribute, they can still be different objects.

+6
source

The class name is an attribute of the class object itself. Usually, when you define a class, you bind it to a variable (with the class name), but the class name will still be stored inside the class object itself.

And in your case, you create two new objects that are different from each other, but both of them are classes and have the same name. And they are not bound to a variable in the namespace in the same way as a regular class.

+5
source

Source: https://habr.com/ru/post/1491333/


All Articles