MalikDeveloper2077
@MalikDeveloper2077

Как создавать методы с декоратором динамически в Python?

У меня есть класс

class SomeMixin:
    permissions = (SomePermission,)
    methods = ('GET',)

    @list_route(methods=methods, url_path='en', permission_classes=permissions)
    def en_list(self):
        return get_translated_objects(self, 'en')

    @list_route(methods=methods, url_path='ru', permission_classes=permissions)
    def ru_list(self):
        return get_translated_objects(self, 'ru')

    @detail_route(methods=methods, url_path='en', permission_classes=permissions)
    def en_detail(self):
        return get_translated_object(self.get_object(), 'en')

    @detail_route(methods=methods, url_path='ru', permission_classes=permissions)
    def ru_detail(self):
        return get_translated_object(self.get_object(), 'ru')


В будущем у меня может быть больше языков, и это не очень хорошее решение.
Я думал создать цикл по списку языков и добавить методы в класс с помощью setattr (self, func_name, func), например:
langs = ('en', 'ru')
for lang in langs:
    setattr(self, func.__name__, func)


Но мне нужно добавить еще и декоратор к каждой функции, как я могу это сделать?
  • Вопрос задан
  • 87 просмотров
Решения вопроса 2
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
f = detail_route(methods=methods, url_path=lang, permission_classes=permissions)(func)
setattr(self, func.__name__, f)
Ответ написан
Комментировать
@cython
Декоратор - функция, в которую передаётся другая функция, в результате чего образуется новая функция. Следовательно мы можем просто вызвать декоратор с функцией как аргументом:
langs = ('en', 'ru')


for lang in langs:
	setattr(self, f"{func.__name__}_list", list_route(
		methods=self.methods,
		url_path=lang,
		permission_classes=self.permissions
	)(lambda x: get_translated_objects(x, lang)))

	setattr(self, f"{func.__name__}_detail", detail_route(
		methods=self.methods,
		url_path=lang,
		permission_classes=self.permissions
	)(lambda x: get_translated_objects(x.get_object(), lang)))
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы