библиотека python для декоратора - PullRequest
2 голосов
/ 15 июля 2011

Я получил довольно странное поведение с библиотекой декоратора, которое объясняется в следующем коде:

from decorator import decorator    

@decorator
def wrap(f, a, *args, **kwargs):
    print 'Decorator:', a, args, kwargs
    return f(a, *args, **kwargs)

def mywrap(f):
    def new_f(a, *args, **kwargs):
        print 'Home made decorator:', a, args, kwargs
        return f(a, *args, **kwargs)
    return new_f

@wrap
def funcion(a, b, *args, **kwargs):
    pass

@mywrap
def myfuncion(a, b, *args, **kwargs):
    pass

funcion(1, b=2)
myfuncion(1, b=2)

При выполнении этого сценария печатается:

$ python /tmp/test.py 
Decorator: 1 (2,) {}
Home made decorator: 1 () {'b': 2}

скрывается 'decorator'kwargs внутри args, как я могу решить это без использования "домашнего" декоратора.

Спасибо.

1 Ответ

5 голосов
/ 15 июля 2011

Только потому, что вы вызываете , функция с b=2 не делает b аргументом ключевого слова;b - это позиционный аргумент в исходной функции.Если бы не было аргумента с именем b и вы указали b=2, , тогда b станет ключевым аргументом. Поведение

decorator на самом деле является наиболее правильным;генерируемая оболочка имеет ту же сигнатуру, что и funcion(), тогда как оболочка, созданная вашим «самодельным» декоратором, не имеет b в качестве именованного аргумента.«Самодельная» оболочка «неправильно» помещает b в kwargs, поскольку подпись myfuncion(), которая дает понять, что b не является ключевым словом arg, скрыта от вызывающей стороны.

Сохранение подписи функции - это функция, а не ошибка, в decorator.

...