How do I check (at runtime) if one class is a subclass of another?

PythonSubclassAssert

Python Problem Overview


Let's say that I have a class Suit and four subclasses of suit: Heart, Spade, Diamond, Club.

class Suit:
   ...
class Heart(Suit):
   ...
class Spade(Suit):
   ...
class Diamond(Suit):
   ...
class Club(Suit):
   ...

I have a method which receives a suit as a parameter, which is a class object, not an instance. More precisely, it may receive only one of the four values: Heart, Spade, Diamond, Club. How can I make an assertion which ensures such a thing? Something like:

def my_method(suit):
   assert(suit subclass of Suit)
   ...

I'm using Python 3.

Python Solutions


Solution 1 - Python

You can use issubclass() like this assert issubclass(suit, Suit).

Solution 2 - Python

issubclass(class, classinfo)

Excerpt:

> Return true if class is a subclass (direct, indirect or virtual) of > classinfo.

Solution 3 - Python

You can use isinstance if you have an instance, or issubclass if you have a class. Normally thought its a bad idea. Normally in Python you work out if an object is capable of something by attempting to do that thing to it.

Solution 4 - Python

The issubclass(sub, sup) boolean function returns true if the given subclass sub is indeed a subclass of the superclass sup.

Solution 5 - Python

issubclass minimal runnable example

Here is a more complete example with some assertions:

#!/usr/bin/env python3

class Base:
    pass

class Derived(Base):
    pass

base = Base()
derived = Derived()

# Basic usage.
assert issubclass(Derived, Base)
assert not issubclass(Base, Derived)

# True for same object.
assert issubclass(Base, Base)

# Cannot use object of class.
try:
    issubclass(derived, Base)
except TypeError:
    pass
else:
    assert False

# Do this instead.
assert isinstance(derived, Base)

GitHub upstream.

Tested in Python 3.5.2.

Solution 6 - Python

According to the Python doc, we can also use class.__mro__ attribute or class.mro() method:

class Suit:
    pass
class Heart(Suit):
    pass
class Spade(Suit):
    pass
class Diamond(Suit):
    pass
class Club(Suit):
    pass

>>> Heart.mro()
[<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>]
>>> Heart.__mro__
(<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>)

Suit in Heart.mro()  # True
object in Heart.__mro__  # True
Spade in Heart.mro()  # False

Solution 7 - Python

You can use the builtin issubclass. But type checking is usually seen as unneccessary because you can use duck-typing.

Solution 8 - Python

Using issubclass seemed like a clean way to write loglevels. It kinda feels odd using it... but it seems cleaner than other options.

class Error(object): pass
class Warn(Error): pass
class Info(Warn): pass
class Debug(Info): pass

class Logger():
    LEVEL = Info

    @staticmethod
    def log(text,level):
        if issubclass(Logger.LEVEL,level):
            print(text)
    @staticmethod
    def debug(text):
        Logger.log(text,Debug)   
    @staticmethod
    def info(text):
        Logger.log(text,Info)
    @staticmethod
    def warn(text):
        Logger.log(text,Warn)
    @staticmethod
    def error(text):
        Logger.log(text,Error)

Solution 9 - Python

#issubclass(child,parent)

class a:
	pass
class b(a):
	pass
class c(b):
	pass

print(issubclass(c,b))#it returns true

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsnakileView Question on Stackoverflow
Solution 1 - Pythonuser97370View Answer on Stackoverflow
Solution 2 - PythonKatrielView Answer on Stackoverflow
Solution 3 - PythonDavid HeffernanView Answer on Stackoverflow
Solution 4 - PythonJameer MulaniView Answer on Stackoverflow
Solution 5 - PythonCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 6 - PythonYaOzIView Answer on Stackoverflow
Solution 7 - PythonXORcistView Answer on Stackoverflow
Solution 8 - PythonJon DonnellyView Answer on Stackoverflow
Solution 9 - PythonVigneshwaran NarayananView Answer on Stackoverflow