Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - isinstance() not working as I'd expect

I have a class called Route (with its own __repr__() function), and an instance of a Route called default_route. However, if I call isinstance(default_route,Route), it unexpectedly returns False, viz:

[Dbg]>>> default_route
Route(office(235)=323-654-3242)
[Dbg]>>> isinstance(default_route,Route)
False
[Dbg]>>> default_route.__class__
<class 'route.Route'>
[Dbg]>>> Route
<class 'route.Route'>
[Dbg]>>> type(default_route)
<class 'route.Route'>
[Dbg]>>> type(default_route) is Route
False

The class definition is really straightforward and uncomplicated:

class Route(object):
    def __init__(self, phone, condition=None):
        self.phone=phone
        self.condition=condition
        self.choice_name=None

I'm just baffled by this; why would isinstance() not return True above?

like image 566
W. Sadkin Avatar asked May 23 '18 01:05

W. Sadkin


People also ask

How do I use Isinstance in Python?

Python isinstance() FunctionThe isinstance() function returns True if the specified object is of the specified type, otherwise False . If the type parameter is a tuple, this function will return True if the object is one of the types in the tuple.

Should I use Isinstance or type Python?

Conclusions. isinstance is usually the preferred way to compare types. It's not only faster but also considers inheritance, which is often the desired behavior. In Python, you usually want to check if a given object behaves like a string or a list, not necessarily if it's exactly a string.

Should you use Isinstance Python?

If you need to check the type of an object, it is recommended to use the Python isinstance() function instead. It's because isinstance() function also checks if the given object is an instance of the subclass.

What is the difference between the type () and Isinstance () in Python?

Python : Difference between type() and isinstance() type() simply returns the type of an object. Whereas, isinstance(): returns true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof.


1 Answers

This could easily happen if you did the following:

  1. import route and create default_route using route.Route
  2. Invoke reload(route) to pull in some code changes to the module (or just for fun; doesn't matter if the module is unchanged, reload will still reload it)

You could encounter this in a similar way if default_route was also defined in route, and you did from route import Route, then reload-ed route, then did from route import default_route (order of importing Route and default_route is irrelevant, as long as a reload occurred between them, and the older one was not reimported). Either way, you have an instance and a class from subtly different versions of the module; they might look the same, have the same behaviors, etc., but they are not the same module, and therefore not the same classes, instances, etc.

In either case, a quick check would be to invoke default_route.__class__ is Route; if that evaluates to True, it's possible you've got some weird ABC based class with a broken __subclasshook__, but more likely it will evaluate to False, indicating that the two classes, despite the matching name, actually originate from independent loads of the module.

like image 171
ShadowRanger Avatar answered Oct 16 '22 05:10

ShadowRanger