How to run code when a class is subclassed

0 votes

Is there a way to trigger code when my class is subclassed?

class SuperClass:
    def triggered_routine(subclass):
        print("was subclassed by " + subclass.__name__)

magically_register_triggered_routine()

print("foo")

class SubClass0(SuperClass):
    pass

print("bar")

class SubClass1(SuperClass):
    print("test")

Should output

foo
was subclassed by SubClass0
bar
test
was subclassed by SubClass1
Nov 20, 2020 in Python by anonymous
• 10,420 points
32 views

1 answer to this question.

0 votes

Classes (by default) are instances of the type. Just as an instance of a class Foo is created by foo = Foo(...), an instance of type (i.e. a class) is created by myclass = type(name, bases, clsdict).

If you want something special to happen at the moment of class-creation, then you have to modify the thing creating the class -- i.e. type. The way to do that is to define a subclass of type -- i.e. a metaclass.

A metaclass is to its class as a class is to its instance.

In Python2 you would define the metaclass of a class with

class SuperClass:
    __metaclass__ = Watcher

where Watcher is a subclass of type.

In Python3 the syntax has been changed to

class SuperClass(metaclass=Watcher)

Both are equivalent to

Superclass = Watcher(name, bases, clsdict)

wherein this case, name equals the string 'Superclass', and bases is the tuple (object, ). The clsdict is a dictionary of the class attributes defined in the body of the class definition.

Note the similarity to myclass = type(name, bases, clsdict).

So, just as you would use a class's __init__ to control events at the moment of an instance's creation, you can control events at the moment of a class's creation with a metaclass's __init__:


class Watcher(type):
    def __init__(cls, name, bases, clsdict):
        if len(cls.mro()) > 2:
            print("was subclassed by " + name)
        super(Watcher, cls).__init__(name, bases, clsdict)

class SuperClass:
    __metaclass__ = Watcher


print("foo")

class SubClass0(SuperClass):
  pass

print("bar")

class SubClass1(SuperClass):
  print("test")

prints

foo
was subclassed by SubClass0
bar
test
was subclassed by SubClass1
answered Nov 20, 2020 by Gitika
• 65,870 points

Related Questions In Python

0 votes
1 answer

How to iterate over a string when there is successive increase in its length?

The following code might help -  mystring = ...READ MORE

answered Jul 22, 2019 in Python by Arvind
• 2,980 points
86 views
0 votes
0 answers

But when I run this, I get NameError: name 'alphabeta' is not defined error. How to solve this?

tree = [[[5, 1, 2], [8, -8, ...READ MORE

Sep 5, 2020 in Python by MUHAMMAD
• 160 points

retagged Sep 7, 2020 by Gitika 160 views
0 votes
1 answer

when I run this, I get NameError: name 'state' is not defined error. How to solve this?

Hi@MUHAMMAD, I tried to run the exact code ...READ MORE

answered Sep 8, 2020 in Python by MD
• 95,060 points
452 views
+1 vote
1 answer

How to check if a string is null in python

Try this: if cookie and not cookie.isspace(): # the ...READ MORE

answered Aug 20, 2018 in Python by Priyaj
• 58,100 points
17,941 views
0 votes
2 answers
+1 vote
2 answers

how can i count the items in a list?

Syntax :            list. count(value) Code: colors = ['red', 'green', ...READ MORE

answered Jul 6, 2019 in Python by Neha
• 330 points

edited Jul 8, 2019 by Kalgi 1,833 views
0 votes
0 answers
+4 votes
6 answers

Lowercase in Python

You can simply the built-in function in ...READ MORE

answered Apr 11, 2018 in Python by hemant
• 5,810 points
1,416 views
0 votes
1 answer

how to run test cases of different modules with same marker at a time using pytest

Hey,@Nikitha, Suppose you have multiple files say test_sample1.py, test_sample2.py. To ...READ MORE

answered Apr 28, 2020 in Python by Gitika
• 65,870 points
88 views
0 votes
1 answer

How to create a unicode string in python with the string eg: This is a string?

Hey, @Roshni, It is very simple to execute, ...READ MORE

answered Jun 23, 2020 in Python by Gitika
• 65,870 points
105 views