prosseek
prosseek

Reputation: 191099

User defined type checking in python: "type(A()) is A" returns false

From this post - What's the canonical way to check for type in Python?, I could use this code to check object o is string type.

o = "str"; print type(o) is str --> True

However, with user defined type, type(a) is A doesn't seem to work.

class A:
    def hello(self):
        print "A.hello"
a = A()

print type(a) is A # --> False
print type(a) == A # --> False

Why is this? How can I get the correct type checking for user defined type? I use python 2.7 on Mac OS X.

PS: This is a question out of curiosity, as I got this example from this book to get true as a result, but I got false. I understand that Duck typing is a preferred way in python. (https://stackoverflow.com/a/154156/260127)

ADDED

rodrigo's answer works for me. Using 'isinstance' doesn't give me an exact type, it just tests if an object is an instance of a class or a subclass.

class C(A):
    def hello(self):
        print "C.hello"

a = A()
c = C()

print isinstance(a, A) --> True
print isinstance(c, A) --> True
print isinstance(a, C) --> False
print isinstance(c, C) --> True
print "----"
print type(a) == A --> True
print type(c) == A --> False

ADDED 2

jdurango's answer (a.__class__ is A) gave me pretty interesting Java equivalent.

a.getClass() == A.class <--> a.__class__ == A (a.__class__ is A)
a isinstance A <--> isinstance(a, A)
c isinstance A <--> isinstance(c, A)

I don't know which copied which.

Upvotes: 9

Views: 3517

Answers (4)

Dustin
Dustin

Reputation: 1026

Why not use isinstance(instance, class)?

>>> class A:
...     def hello(self):
...        print "A.hello"
... 
>>> type(A)
<type 'classobj'>
>>> a = A()
>>> type(a)
<type 'instance'>
>>> isinstance(a, A)
True

Upvotes: 7

m.brindley
m.brindley

Reputation: 1228

If you are defining a like a = A() then a is an instance of the class A. If you are just doing a = A, then the name a points to the class object.

You probably want an instance of A and can then test that with

>>> a = A()
>>> isinstance(a, A)
True

New style classes will test True to type(A()) == A though.

Upvotes: 2

jdurango
jdurango

Reputation: 543

Try this

print a.__class__ is A
True

Upvotes: 7

rodrigo
rodrigo

Reputation: 98496

You should use the new-style classes:

class A(object):
    pass

That is, derive it from object.

The problem is that object of old-style are implemented as if all of them were of type instance.

Deriving directly or indirectly from object will solve this issue. Or moving to Python3, where there is no more old-style classes.

Upvotes: 14

Related Questions