Python - Accessing Parent Class Decorators Inside Class Declaration
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 asnamespace = 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"