5

I have the following code:

>>> class MyClass:
    pass

>>> myObj=MyClass()

>>> type(myObj)
<type 'instance'>     <==== Why it is not type MyClass ?

>>> type(MyClass)
<type 'classobj'>  <=== Why it is not just 'MyClass'?

>>> isinstance(myObj, instance)  <==== Why the 'instance' is not defined?

Traceback (most recent call last):
  File "<pyshell#91>", line 1, in <module>
    isinstance(myObj, instance)
NameError: name 'instance' is not defined

>>> isinstance(myObj, MyClass)
True

>>> myObj.__class__
<class __main__.MyClass at 0x0000000002A44D68> <=== Why different from type(myObj) ?

It seems Python has some extra indirection between a class and its instance type.

I am used to C#. In C#, typeof(MyClass) will just return the MyClass.

Add 1

Below is some comparison between 2.7.6 and 3.4.1.

I am wondering how the == operator is implemented in Python.

enter image description here

smwikipedia
  • 61,609
  • 92
  • 309
  • 482
  • Not sure yet... don't know where it is defined. – smwikipedia Sep 15 '14 at 00:46
  • But you wrote it no? – Padraic Cunningham Sep 15 '14 at 00:47
  • @PadraicCunningham -- nope, Python actually does that. It literally states that the type of an old-style class is 'instance'. – Michael0x2a Sep 15 '14 at 00:49
  • @Michael0x2a, why is it after `>>> `then? – Padraic Cunningham Sep 15 '14 at 00:50
  • Uh.. because it's an interactive interpreter session? I don't know what you're confused about, padraic. – roippi Sep 15 '14 at 00:52
  • @PadraicCunningham -- Are we talking about `>>> isinstance(myObj, instance)`? I think that was just OP trying to test and see if Python had an 'instance' keyword or if Python defined it somewhere (which there it doesn't -- Python threw a NameError after that line). – Michael0x2a Sep 15 '14 at 00:52
  • @Michael0x2a, yes, that is actually part of the question which has not been answered, that is why I asked the OP what it was in the hope they might explain what they expected it to be – Padraic Cunningham Sep 15 '14 at 00:54
  • 1
    @PadraicCunningham -- sorry, I'm still a little confused by what you mean. If I understand correctly, in the line above, OP did `type(myObj)` and was told by Python that the type was `instance`. If `type(myObj) --> instance`, then it would make sense that the inverse relationship is true -- `isinstance(myObj, instance) --> True`. So, OP tested that, and was confused because `instance` apparently doesn't exist when doing `type(myObj)` seemed to imply it does. So, OP was confused, since he/she expected `isinstance(myObj, instance)` to return 'True', not an exception, so asked this question. – Michael0x2a Sep 15 '14 at 01:00
  • @Michael0x2a yes, that's my confusion. – smwikipedia Sep 15 '14 at 01:48

1 Answers1

9

This is because you're using old-style classes. Instead of doing:

class MyClass:
    pass

You need to do:

class MyClass(object):
    pass

...in order to use new-style classes. Now, if you do type(myObj), you get back <class '__main__.MyClass'> as expected.

In fact, one of the major reasons why Python introduced new-style classes was exactly because of the problem you observed:

New-style classes were introduced in Python 2.2 to unify classes and types. A new-style class is neither more nor less than a user-defined type. If x is an instance of a new-style class, then type(x) is typically the same as x.__class__ (although this is not guaranteed - a new-style class instance is permitted to override the value returned for x.__class__).

The major motivation for introducing new-style classes is to provide a unified object model with a full meta-model. It also has a number of practical benefits, like the ability to subclass most built-in types, or the introduction of “descriptors”, which enable computed properties.

(source)

This is a bit of a kludge, having to extend object, but thankfully in Python 3, old-style classes were removed altogether so declaring the class using either forms does the same thing.

Community
  • 1
  • 1
Michael0x2a
  • 58,192
  • 30
  • 175
  • 224
  • @smwikipedia It really depends. There are still libraries (unfortunately) that have not been rewritten to deal with Python 3. If you find yourself having to use one of those, you'll have to stick with 2. Fortunately, it's pretty easy in general to write code that works in both. – Two-Bit Alchemist Sep 15 '14 at 00:46
  • @Two-BitAlchemist thanks for reminding. I am trying to use scikit-learn for some machine learning experiment. Fortunately, they support `Python (>= 2.6 or >= 3.3)` – smwikipedia Sep 15 '14 at 01:51