Skip to content Skip to sidebar Skip to footer

Python - Accessing Parent Class Decorators Inside Class Declaration

Let's say I have this class: class Foo: @classmethod def some_decorator(cls, ...): ... And then I create a subclass which uses the parent class decorator: class Ba

Solution 1:

This is done with a metaclass that implements a __prepare__ method. Excerpt from the docs:

3.3.3.4. Preparing the class namespace

Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a __prepare__ attribute, it is called as namespace = metaclass.__prepare__(name, bases, **kwds) (where the additional keyword arguments, if any, come from the class definition).

To put it in simple terms: You make your __prepare__ method return a dictionary that contains an entry for the decorator. Proof of concept:

classMyMeta(type):
    def__prepare__(name, bases):
        return {'x': 'foobar'}

classMyClass(metaclass=MyMeta):
    print(x)  # output: foobar

Solution 2:

I have looked inside the library you are talking about and the Lexer class inherits a metaclass:

class Lexer(metaclass=LexerMeta):

Inside the LexerMeta you can find the following:

@classmethoddef__prepare__(meta, name, bases):
        d = LexerMetaDict()

        def_(pattern, *extra):
            patterns = [pattern, *extra]
            defdecorate(func):
                pattern = '|'.join(f'({pat})'for pat in patterns )
                ifhasattr(func, 'pattern'):
                    func.pattern = pattern + '|' + func.pattern
                else:
                    func.pattern = pattern
                return func
            return decorate

        d['_'] = _
        d['before'] = _Before
        return d

A metaclass is used to create the class object which then is used to instantiate objects. From what i can see in that method is that here d['_'] = _ that metaclass dynamically attaches the _ method to the class you are going to use.

This means that what they are doing is not much different from:

classBar:@staticmethoddefsome_decorator(f):
        ...

    @some_decoratordefsome_function(self):
        ...

Post a Comment for "Python - Accessing Parent Class Decorators Inside Class Declaration"