I have a method that accepts a parameter that can be of several types, and has to do one thing or other depending on the type, but if I check the type of said parameter, I don't get the 'real' type, I always get <type 'instance'>
, and that is messing up with my comparisons.
I have something like:
from classes import Class1
from classes import Class2
# Both classes are declared in the same file.
# I don't know if that can be a problem #
# ... #
def foo(parameter)
if (type(parameter) == type(Class1()):
# ... #
elif (type(parameter) == type(Class2()):
# ... #
And as type(parameter)
returns <type 'instance'>
and type(Class1())
is <type 'instance'>
as well, it turns out that even if the parameter is an instance of Class2, it is going into the first comparison...
By the way, str(parameter.__class__)
properly shows classes.Class1
. I guess I could always use that, but I would like to understand what's going on... I have made tenths of comparisons like this and all them worked properly...
Thank you!! :)
Old-style classes do that. Derive your classes from object
in their definitions.
you should really use isinstance:
In [26]: def foo(param):
....: print type(param)
....: print isinstance(param, Class1)
....:
In [27]: foo(x)
<type 'instance'>
True
Type is better for built-in types.
The fact that type(x)
returns the same type object for all instances x
of legacy, aka old-style, classes, is one of many infuriating defects of those kinds of classes -- unfortunately they have to stay (and be the default for a class without base) in Python 2.*
for reasons of backwards compatibility.
Nevertheless, don't use old-style classes unless you're forced to maintain a bunch of old, legacy code (without a good test suite to give you the confidence to try and switch kind o classes). When a class has no "natural" bases, subclass it from object
rather than from nothing. Alternatively, your module, at the top, can set
__metaclass__ = type
which changes the default from the crufty, legacy old-style classes, to the shiny bright new-style ones -- while explicitly inheriting from object
is usually preferred ("explicit is better than implicit"), the module-global setting of __metaclass__
may feel "less invasive" to existing old modules where you're switching from old to new classes, so it's offered as a possibility.