Reputation: 12665
Say I have a very simple class like the following:
class myClass:
def __init__(self):
self.myProp = 2
If I instantiate using the parentheses/brackets, everything works as I expect:
>>> a = myClass()
>>> a.myProp
2
However, if I don't use the parentheses/brackets on the two lines above, i.e.:
>>> a = myClass
I get the following error:
>>> a.myProp
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
a.myProp
AttributeError: class myClass has no attribute 'myProp'
If I print the object,
>>> a = myClass
>>> a
I get
<class __main__.myClass at 0x0275C538>
It seems that a
is an instance of the class, but somehow is not initialized.
In other languages, I would expect a compile error if trying to cast a class instance into an object without initalizing it (e.g. in C#, myClass a = new myClass();
would work fine but myClass a = new myClass;
would return a compile error).
So my question is: what is, technically speaking, the object a = myClass
without parentheses/brackets?
Upvotes: 16
Views: 9272
Reputation: 309939
a
is the class itself -- In python, classes are first class objects1. You can pass them around as parameters, alias them to different names (as you've done in your example) and then you can instances from any reference that you have in the current namespace.
a = myClass # a and myClass identical at this point. The interpretter won't care which you use.
a_instance = a() # instance of myClass
def make_instance(cls):
return cls()
another_instance = make_instance(a)
yet_another_instance = make_instance(myClass)
You see, python doesn't have any "compile time checking" because really -- there is no compile time. Python code gets interpreted at runtime. True, you can have SyntaxError
s pop up at when you import something, but that is still during runtime.
1No pun intended
Upvotes: 15
Reputation: 3877
Everything in Python is an object and thus an instance of a class, including classes. There is nothing special about manipulating classes or passing them around as variables. Thus your variables a
and MyClass
, which refer to the same object, are just the object that is MyClass
.
>>> class R: pass # In Python 2, you would need class R(object): pass
>>> r = R()
Now we have two variables, R
and r
. r
is an instance of class R
. The trick here is that R
is an instance of class type
, which is why we call R
a class. Both r
and R
are instances of object
, which is why we call both of them objects. And R
is a subclass of class object
because R
is a class.
>>> isinstance(R, type)
True
>>> isinstance(r, R)
True
>>> issubclass(R, object)
True
>>> isinstance(r, object)
True
>>> isinstance(type, object)
True
>>> isinstance(type, type)
True
Every Python object is an instance of object
and every Python class is a subclass of object
and every Python class is an instance of type
.
Note that what I'm saying is true in Python 3 and for Python 2 "new style" classes. Do not concern yourself with Python old-style classes.
Upvotes: 3
Reputation: 1649
It's a reference to the class itself, rather than a reference to an instance of the class. Note the difference:
>>> a = myClass
>>> a
<class __main__.myClass at 0x10cd1de20>
>>> b = myClass()
>>> b
<__main__.myClass instance at 0x10cd8efc8>
Upvotes: 11