Я знаю, что это старый вопрос, но это решение еще не упоминалось, надеюсь, оно может помочь кому-то даже сегодня, через 8 лет.
Итак, как насчет упаковки обертки? Предположим, нельзя ни изменить декоратор, ни украсить эти методы в init (они могут быть украшены @property или чем-то еще). Всегда есть возможность создать собственный декоратор для конкретного класса, который будет захватывать себя и впоследствии вызывать исходный декоратор, передавая ему атрибут времени выполнения.
Вот рабочий пример (для f-строк требуется Python 3.6 ):
import functools
# imagine this is at some different place and cannot be changed
def check_authorization(some_attr, url):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"checking authorization for '{url}'...")
return func(*args, **kwargs)
return wrapper
return decorator
# another dummy function to make the example work
def do_work():
print("work is done...")
###################
# wrapped wrapper #
###################
def custom_check_authorization(some_attr):
def decorator(func):
# assuming this will be used only on this particular class
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
# get url
url = self.url
# decorate function with original decorator, pass url
return check_authorization(some_attr, url)(func)(self, *args, **kwargs)
return wrapper
return decorator
#############################
# original example, updated #
#############################
class Client(object):
def __init__(self, url):
self.url = url
@custom_check_authorization("some_attr")
def get(self):
do_work()
# create object
client = Client(r"https://stackoverflow.com/questions/11731136/class-method-decorator-with-self-arguments")
# call decorated function
client.get()
выход:
checking authorisation for 'https://stackoverflow.com/questions/11731136/class-method-decorator-with-self-arguments'...
work is done...
person
Michal
schedule
04.02.2021