2

This may turn out to be a basic question but i have spent hours on looking this up. Clearly, i am missing something in the internals of how objects/instances as well as class objects are created. Any help is appreciated.

Let me first create objects using standard way.

As can be seen below, two instances (object_1 and object_2) have the same class object (class_object_1 and class_object_2 are same) and assertion succeeds

class MyClass:
     pass

if __name__=='__main__':

     object_1 = MyClass()
     object_2 = MyClass()

     class_object_1 = object_1.__class__
     class_object_2 = object_2.__class__

     assert(class_object_1 == class_object_2)

However, when i try repeating this by dynamically creating class object using type, i do not get same object and assertion fails

cls_object_1 = type("MyClass", (), {})
cls_object_2 = type("MyClass", (), {})
assert(cls_object_1 == cls_object_2)

I further repeated this using yet another way and assertion fails again.

klass_object_1 = type.__new__(type, "MyClass", (), {})
klass_object_2 = type.__new__(type, "MyClass", (), {})
assert(cls_object_1 == cls_object_2)

Why are these ways not equivalent? What extra thing happens in first way that returns the same class object for two instances?

1
  • @Selcuk - thanks. you are saying that type() creates class object but its different every time (i.e type object get instatiated to class object every time). However, when using MyClass() to create instances, i am re-using same class object? How does that happen? Commented Sep 8, 2020 at 6:23

1 Answer 1

2

type() creates a new type object. You are basically creating two different classes with the same name (similar to importing two classes that have the same name from different modules).

In your first example both instances are created from the same class, that's why their .__class__ attribute return the exact same object.

You can simulate the same thing using "normal" classes by defining it multiple times:

class MyClass:
  pass

obj1 = MyClass()

class MyClass:
  pass

obj2 = MyClass()

print(obj1.__class__ is obj2.__class__)

This should print False.

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

2 Comments

thanks. this explains it. On a related note, can you please fill in some more detail here to resolve my confusion? In my original "normal" method, obj1 = MyClass(). This call presumably first creates class object (if it doesnt exists) and then instantiates class object into obj1. What happens when i do obj2 = MyClass()? Does it know that class object already exist in globals of that module and it reuses it to instantiate obj2?
No, the class object has already been created by the class keyword. You are only instantiating it using obj1 = MyClass(). Try adding a print(MyClass) line right after you define your class to confirm that.

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.