isinstance without importing candidates
Asked Answered
C

3

25

We have a function which takes a variety of different types of input: a function, a string, a compiled regular expression, a Hamcrest Matcher, and filters a list appropriately based on the type of the input.

We're currently using isinstance(our_filter, hamcrest.matcher.Matcher), but this requires us to require Hamcrest to be installed.

We're considering using string matches on inspect.getmro(type(POSSIBLE_MATCHER)); but this feels unclean. There might also be options with try/except around the import statement.

What's the best approach?


With help from @dblslash, this is the best I've got so far:

[x.__module__+"."+x.__name__ for x in inspect.getmro(type(POSSIBLE_MATCHER))] ['hamcrest.core.core.isequal.IsEqual', 'hamcrest.core.base_matcher.BaseMatcher', 'hamcrest.core.matcher.Matcher', 'hamcrest.core.selfdescribing.SelfDescribing', '__builtin__.object']

Collected answered 6/6, 2013 at 14:17 Comment(1)
I had similar issue and ended up with using if str(data.__class__) == '<class 'somemodule.someclass'>: .... I would not use try/catch because it requires importing the module at the first use, which can in some cases cause annoying delay and of course takes memory if you then finally find that you actually do not need the imported module because the input was of different type.Hercule
B
26

Using type(POSSIBLE_MATCHER).__name__ is IMHO a fairly elegant solution for type checking without having to import the module.

Bac answered 6/6, 2013 at 14:19 Comment(0)
H
7

If you want to cater for inheritance, using type(POSSIBLE_MATCHER).__name__ will not cut it. You could then check against all types in the inheritance chain:

class_string in [t.__name__ for t in type(POSSIBLE_MATCHER).__mro__]
Hillard answered 10/8, 2020 at 9:17 Comment(0)
G
1

even though this is a quite old question, I thought I'll share my solution for this:

  • use a conditional import and set a flag to check if the import was successful before isinstance()! (after all if the module cannot be imported isinstance should always return False)

e.g. something like this:

try:
    import somemodule

    _import_OK = True
except ImportError:
    _import_OK = False


# and then later in the code:
if _import_OK:
    q = isinstance(x, somemodule.something)
else
    q = False
Glutelin answered 23/1, 2022 at 0:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.