6

I want to check if an object or variable is an instance of the specified class type, but using the name of this class, not its type. Something like this:

class A: pass

class B(A): pass

class C(B): pass

c_inst = C()

# Not working, isinstance expects the type:
ok = isinstance(c_inst, 'A')

Are there any alternatives? I want to use the class name, so isinstance(c_inst, A) is not available in this case.

1

3 Answers 3

5

If you only have the class name as a string, you could do this

>>> class Foo:pass
... 
>>> foo = Foo()
>>> foo.__class__.__name__ == 'Foo'
True
>>> foo.__class__.__name__ == 'Bar'
False

However this isn't very reliable, because Foo.__class__.__name__ is writeable

>>> foo.__class__.__name__ = 'Baz'
>>> foo.__class__.__name__ == 'Foo'
False

For superclasses, you could do something like

foo.__class__.__name__ == 'X' or 'X' in [c.__name__ for c in foo.__class__.__bases__]

though this won't pick up object.

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

Comments

3

Came up with this way, note: the class you are checking must be in globals though:

def isinstance_string(variable, string):
    cls = globals().get(string, None)
    if isinstance(cls, type): # Check if cls is actually a class
        return isinstance(variable, cls)
    return False

class A: pass

class B(A): pass

class C(B): pass

c_inst = C()
ok = isinstance_string(c_inst, 'A')

3 Comments

What is cls or Unused meant to do please?
@Guimoute it was meant to replace None by a class that would never match. But later realized it might be problematic if cls was not a class so used inspect.isclass which made it redundant. Edited the answer and removed that.
inspect.isclass(cls) can just be isinstance(cls, type)
0

I tried the globals() method suggested by @Abdul, but that did not work in some cases, so I modified it slightly. This provides the extra feature of being able to use type coersion.

isinstance(x,getattr(globals()['__builtin__'],type_as_string))

The benefit is that we can also use this to generate an instance of an arbitrary type, and avoid Python trying to decide what type that is at assignment time.

cls = getattr(globals()['__builtin__'],type_as_string)
inst = cls(value_to_create)

Update (simplified, ~ Python3.11+ ??), i.e. on more recent Python.

cls = getattr(__builtins__,type_as_string)

e.g. (updated)

cls1 = getattr(__builtins__,'str')
cls2 = getattr(__builtins__,'float')
cls3 = getattr(__builtins__,'complex')
cls4 = getattr(__builtins__,'int')
inst1 = cls1(1)
inst2 = cls2(1)
inst3 = cls3(1)
inst4 = cls4(1)

print(type(cls1), f"'{inst1}'", type(inst1))
print(type(cls2), f"'{inst2}'", type(inst2))
print(type(cls3), f"'{inst3}'", type(inst3))
print(type(cls4), f"'{inst4}'", type(inst4))

print('str', isinstance(inst1, str))
print('float', isinstance(inst2, float))
print('complex', isinstance(inst3, complex))
print('int', isinstance(inst4, int))

for inst in (inst1, inst2, inst3, inst4):
    print(inst,
        "is complex? =",
        isinstance(inst,getattr(__builtins__,"complex")))

Output:

<class 'type'> '1' <class 'str'>
<class 'type'> '1.0' <class 'float'>
<class 'type'> '(1+0j)' <class 'complex'>
<class 'type'> '1' <class 'int'>
str True
float True
complex True
int True
1 is complex? = False
1.0 is complex? = False
(1+0j) is complex? = True
1 is complex? = False

Comments

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.