2

I have a list of variables.. inside the list are strings, numbers, and class objects. I need to perform logic based on each different type of data. I am having trouble detecting class objects and branching my logic at that point.

if(type(lists[listname][0]).__name__ == 'str'): # <--- this works for strings
elif(type(lists[listname][0]).__name__ == 'object'): <--- this does not work for classes

in the second line of code above, the name variable contains "Address" as the class name. I was hoping it would contain "class" or "object" so I could branch my program. I will have many different types of objects in the future, so it's a bit impractical to perform logic on every different class name, "Address" "Person" etc

please let me know if my question needs clarification.

thanks!!

4 Answers 4

5

FYI: it also makes a difference if its a new-style class or not:

# python
type(1).__name__
'int'
type('1').__name__
'str'
class foo(object):
  pass
type(foo()).__name__
'foo'
class bar:
  pass
type(bar()).__name__
'instance'

If you can make sure they're all new-style classes, your method will determine the real type. If you make them old-style, it'll show up as 'instance'. Not that I'm recommending making everything all old-style just for this.

However, you can take it one step further:

type(bar().__class__).__name__
'classobj'
type(foo().__class__).__name__
'type'

And always look for 'classobj' or 'type'. (Or the name of the metaclass, if it has one.)

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

1 Comment

ok thanks, I think I understand all these examples. I'ld rather not look for the metaclass because I dont always know what it will be. I was hoping to find a way to detect the base object consistently
3

I think you want the isinstance function.

if isinstance(o, ClassName):

However, you'll need to first verify that o is an object, you can use type for that.

Comments

2

It's common in Python to use exception handling to decide which code path to take; inspecting the exact type of an object (with isinstance()) to decide what to do with it is discouraged.

For example, say that what you want to do is, if it's a string, print it in "title case", and if it's an object, you want to call a particular method on it. So:

try:
    # is it an object with a particular method?
    lists[listname][0].particularMethod()
except AttributeError:
    # no, it doesn't have particularMethod(), 
    # so we expect it to be a string; print it in title case
    print lists[listname][0].title()

3 Comments

+1 Good advice! Type inspecting should be avoided in python even more than in some other languages, so that any compatible object can be used. Python does not define interfaces, because any object should be usable in any place if it implements required methods.
ok I guess I can do this here. it's not really a concern for this app, but for future reference is there a performance concern with using exception handling in this way?
Not a major concern. If you were doing this kajillions of times, you could create a class that inherits from str and implements particularMethod(), and use instances of that class in your list instead of str; then you just call particularMethod() on everything.
-1

If you are only interested in handling two types specifically, you could test for them explicitly using isinstance and then handle the leftovers:

import numbers

for item in list:
    if isinstance(item, basestring): # (str, unicode)
        do_string_thing(item)
    elif isinstance(item, numbers.Real): # (int, float, long)
        do_number_thing(item)
    else:
        do_object_thing(item)

4 Comments

Can someone explain why this was down-voted? I feel like it would be useful for myself and other readers to understand what was wrong with my suggestion.
Some people consider isinstance() a tool of last resort. See canonical.org/~kragen/isinstance for the rationale.
According to PEP 8, "object type comparisons should always use isinstance() instead of comparing types directly."
Yes, isinstance() is better than comparing types, but it's worse than polymorphism.

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.