Function decoration takes place when the class body is being executed, nothing is known about the class itself or its base classes at this time. This means that modifier
decorates the unbound function object and only when func
is actually called on an instance will it be bound.
You could return a wrapper function to replace the decorated function, it'll be bound instead and you'll have access to self
:
from functools import wraps
def modifier(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
# self is an instance of the class
self.data
return func(self, *args, **kwargs)
return wrapper
The wrapper will then be called each time method
is called on an instance.
If you must have access to the base classes at class creation time, you'll have to wait until the class Child
statement has completed execution. Until Python 3.6, that's only possible from a class decorator or metaclass; each is called after the class body is created and you'll have access to (at the least) the base classes.
Using a class decorator, for example:
def modifier(cls):
# cls is the newly created class object, including class attributes
cls.data
return cls
@modifier
class Child(Parent):
def method(self):
pass
Note the location of the decorator now.
Python 3.6 adds an __init_subclass__
method that could also give you that access; the (class) method is called each time a subclass is created of the current class:
class Parent:
def __init_subclass__(cls, **kwargs):
# cls is a subclass of Parent
super().__init_subclass__(**kwargs)
cls.data
data = "Hi!"
class Child(Parent):
def method(self):
pass