Получите доступ к kwargs и args в оболочке декоратора - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть декоратор на основе классов.Проблема в том, что мне нужно иметь доступ к аргам и кваргам с перенесенными функциями, но теперь я не могу и не понимаю почему.Это должно быть легко, но это не для меня.

class limit:
    def __call__(self, fn):
        @wraps(fn)
        # the idea to use signature like (request, *args, **kwargs) is bad. I must accept *args and **kwargs only 
        def wrapper(*args, **kwargs):
             # pdb breakpoint is here
             user = kwargs.get('user') or kwargs.get('request').user // ERROR

             return fn(*args, **kwargs)

        return wrapper

Давайте посмотрим на pdb.Это **** CENSORED **** сумасшедший.

(Pdb) args
args = (<User: dua>,)
kwargs = {}
(Pdb) kwargs
{}
(Pdb) args.args
args = (<User: dua>,)
kwargs = {}
(Pdb) args.args.args.args
args = (<User: dua>,)
kwargs = {}
(Pdb) args.get('user')
args = (<User: dua>,)
kwargs = {}
(Pdb) type(args)
<class 'tuple'>
(Pdb) 

Вопрос в том, как я могу получить доступ к аргументам, kwargs и обрабатывать args как список, а kwargs как dict.

PSЯ не знаю, почему так выглядит args, а kwargs.Почему они так выглядят?


Как уже упоминалось в ответе args является командой pdb.Пользователь repr(args) для просмотра аргументов.

Следующий вопрос - возможные сигнатуры функции: 1) def fn (request, ...) 2) def fn (self, a, b, c и т. Д., User)3) def fn (пользователь)

Есть ли способ справиться со всеми из них одним декоратором?


Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Я закончил с этим решением:

def wrapper(*args, **kwargs):
    user = None
    fn_signature_args = inspect.getfullargspec(fn).args
    # looking for a user in kwargs
    if 'user' in kwargs:
    user = kwargs['user']
    # looking for a user as positional argument
    elif 'user' in fn_signature_args:
    index = fn_signature_args.index('user')
    user = args[index]
    # looking for a user as self or request attribute
    elif fn_signature_args[0] in ('request', 'self'):
    user = args[0].user
0 голосов
/ 11 февраля 2019

Ваш вывод pdb на самом деле не имеет значения, args здесь действует как интерактивная команда pdb.

Для простоты, используйте repr(args) или временное переименование *args аргумент

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...