user1969453
user1969453

Reputation:

discriminating whether python object is subclass of current __init__ method

This is an odd one. I have run into a situation a few times where I would like to do some action at the end of __init__ of a python object. I would like to do the action as the last thing in the __init__ of the true class (leaf class) only. I absolutely do not want to do it if in a superclass of self __init__ method. Is there a good way to do this? I grant it may be a silly thing to do. But it has me curious whether and how it could be done.

Upvotes: 1

Views: 541

Answers (1)

abarnert
abarnert

Reputation: 365807

If you want some code to run in the leaf class, at the end of __init__, without it running in the base class… just override __init__ in the leaf class. For example:

class Base(object):
    def __init__(self):
        print('Base initializing')
class Intermediate(Base):
    pass
class Leaf(Intermediate):
    def __init__(self):
        super(Leaf, self).__init__()
        print('Leaf initializing')

>>> o = Base()
Base initializing
>>> o = Intermediate()
Base initializing
>>> o = Leaf()
Base initializing
Leaf initializing

If you're trying to programmatically detect, from within a method like Base.__init__, whether self is a Base or some subclass of Base… well, usually this is a bad idea, and you actually want to use method overriding, as above. But it can be done easily. For example:

class Base(object):
    def __init__(self):
        if type(self) != Base:
            print('Some subclass of Base initializing')
class Leaf(Base):
    pass

>>> obj = Leaf()
Some subclass of Base initializing

(If you're worried that someone might subvert your hierarchy such that some object that's neither a Base nor a subclass of it might end up calling Base.__init__, and you're sure that would be an evil thing rather than a clever monkeypatching thing, you can always check issubclass.)


If you're trying to programmatically detect, within a method like Base.__init__, whether base is a "real class"… well, you need to define what that means. Does it mean "Not an abstract base class in the PEP3119 sense"? "Has no subclasses defined (yet)"? "Has an implementation for some critical method"? Whatever you want to do is probably doable, but some will be harder than others. (For example, to detect whether anyone has subclassed your class, you'll likely need to build a custom metaclass.)

Upvotes: 5

Related Questions