19

I'm a bit confused about types and classes in Python. For e.g. the following REPL conversation confuses me:

>>> class A: pass
... 
>>> a = A()
>>> type(a)
<type 'instance'>
>>> a.__class__
<class __main__.A at 0xb770756c>
>>> type([])
<type 'list'>
>>> [].__class__
<type 'list'>
>>> type(list)
<type 'type'>
>>> list.__class__
<type 'type'>
>>> type(A)
<type 'classobj'>
>>> A.__class__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class A has no attribute '__class__'
  1. Why is the type and class for inbuilt things (e.g. list here) the same but different for user classes/types?
  2. Isn't every class an instance of some other class (like Class in Java)? Why no __class__ for user defined classes?

Any explanation/further reading which can clarify this behaviour would be much appreciated. TIA.

2
  • 5
    You should define your classes with class A(object). Then you will get <class '__main__.A'> for type(a). Commented Dec 18, 2010 at 19:50
  • This question is similar to: Class vs. Type in Python. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Dec 16, 2024 at 21:28

3 Answers 3

16

You're encountering the different behavior for new style classes versus classic classes. For further reading read this: Python Data Model. Specifically read the section on classes and the difference between new style and classic classes.

Try typing the following into your REPL:

class A: pass
class B(object): pass

and you'll see that you get different results. Here you're dealing with the difference between new style and old style classes. Using Python 2.6.1 here's what I get:

> type(A)
<type "classobj">
> type(B)
<type "type">

which tells you that lists are new style classes and not old style classes. We can further play around with things using list as well:

> type(list)
<type "type">

same as our class B(object): pass result. And also

> c = []
> type(c)
<type "list">

which is telling you about the instance of the object and not it's definition.

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

3 Comments

It seems that my wrong was with not using new typeclasses which ended up giving me weird results (surely for backward compatibility). The link looks interesting. Thanks.
In Python 3.11.9, type(A) returns <class 'type'>
@SmartManoj this answer is out of date, see the other responses
6

It's "Hystorical reasons". Or possible "Histerical". It's all fixed in Python 3:

>>> class A: pass
... 
>>> a = A()
>>> type(a)
<class '__main__.A'>
>>> a.__class__
<class '__main__.A'>
>>> type([])
<class 'list'>
>>> [].__class__
<class 'list'>
>>> type(list)
<class 'type'>
>>> list.__class__
<class 'type'>
>>> type(A)
<class 'type'>
>>> A.__class__
<class 'type'>
>>> class B(object): pass
... 
>>> type(B)
<class 'type'>
>>> b = B()
>>> type(b)
<class '__main__.B'>

2 Comments

That's nice to know. Didn't realize Python 3 had fixed the issue all together. I assume then, that all classes regardless of explicitly deriving from object derive from object then?
Beginner's note that type(class) is invaild, but type(type) is <class 'type'>. the former might be less suprising if you compare to type(def).
3

In Python 3.0, user-defined class objects are instances of the object named type, which is itself a class. • In Python 2.6, new-style classes inherit from object, which is a subclass of type; • classic classes are instances of type and are not created from a class.

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.