I am looking at methods for detecting the type of a variable (list vs string) within python (2.5+), and came across some other answers which seemed overly convoluted.
I have found one can do
x.__class__.__name__
to get a string containing the class name. What, if anything, is wrong with this? Is it not portable? When would it fail?
It'll fail for old-style classes; isinstance() works just fine:
>>> class OldStyle: pass
...
>>> OldStyle.__class__.__name__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: class OldStyle has no attribute '__class__'
>>> isinstance(OldStyle(), OldStyle)
True
Note that it is better to use isinstance() and accept subclasses, including virtual subclasses (via abstract base classes). Don't tie your code to a specific type.
For example, you'd not want to test for obj.__class__.__name__ in ('int', 'float', 'complex') when you could just use isinstance(obj, numbers.Number); that way your code will accept decimal.Decimal objects too.
The problem is that different classes can have the same name.
The straightforward example is for classes defined in different modules (e.g. think of generic common names such as Node or Connection).
However, it's easy to demonstrate this problem even in a single module:
class A(object): pass
B = A
class A(object): pass
C = A
b = B()
c = C()
b.__class__.__name__ == c.__class__.__name__
=> True
type(b) == type(c)
=> False
If you don't have to have string-representation of the class, simply use the type object returned by calling type(obj).
Of course, depending on what you use it for, it might be best to use isinstance instead of dealing with type objects directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With