Как объединить несколько декораторов @staticmethod в одинPython

Программы на Python
Ответить
Anonymous
 Как объединить несколько декораторов @staticmethod в один

Сообщение Anonymous »

Я хочу объединить несколько декораторов @statimethod (назовем их декоратор_1, декоратор_2 и т. д.) в один @staticmethodкомбинированный_декоратор.
В моем случае мне нужно, чтобы декораторы имели доступ к объекту класса, поэтому я не могу объявлять свои декораторы вне класса. Представьте себе, например, декоратор счетчика исключений класса, который будет увеличивать переменную self.Exception_count всякий раз, когда декорированный метод my_func(self) вызывает исключение. Например:

Код: Выделить всё

import functools

class Example:
def __init__(self):
self.exception_count = 0

@staticmethod
def count_exception(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except Exception as e:
print(f"caught: {e}")
self.exception_count += 1

return wrapper

@count_exception
def foo(self):
raise RuntimeError("exception!")

x = Example()
# prints: "exception count: 0"
print(f"exception count: {x.exception_count}")
x.foo()
x.foo()
# prints: "exception count: 2"
print(f"exception count: {x.exception_count}")
В этом игрушечном примере имеется только один декоратор и один метод декоратора. В моем случае у меня много декораторов, много методов оформления, и я всегда использую один и тот же шаблон оформления. Поэтому вместо того, чтобы писать:

Код: Выделить всё

    @decorator_1
@decorator_2
# ...
@decorator_X
def foo():
pass
Мне бы хотелось иметь один @combined_decorator.
Я попробовал следующую реализацию, но она не работает:

Код: Выделить всё

class MyClass:
@staticmethod
def _decorator1(func):
def wrapper(self, *args, **kwargs):
print("static decorator 1")
return func(self, *args, **kwargs)
return wrapper

@staticmethod
def _decorator2(func):
def wrapper(self, *args, **kwargs):
print("static decorator 2")
return func(self, *args, **kwargs)
return wrapper

@staticmethod
def _combined_decorator(func):

@MyClass._decorator1
@MyClass._decorator2
def wrapper(self, *args, **kwargs):
return func(self, *args, **kwargs)

return wrapper

@_combined_decorator
def my_func(self):
print("my func")

x = MyClass()
x.my_func()
Проблема здесь в NameError: имя «MyClass» не определено внутри определения _combined_decorator
У меня есть несколько вариантов: использование @classmethod, изменение @MyClass._decoratorX на @_decoratorX и т. д. Но, похоже, ничего не работает.
Я использую 3.10, поэтому я думаю, что @staticmethod должен иметь возможность вызывать другой @staticmethod внутри того же класса, и это, насколько я понимаю, все, что должно потребоваться.
Есть идеи?

Подробнее здесь: https://stackoverflow.com/questions/791 ... single-one
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»