此系列文档: 1. 我终于弄懂了Python的装璜器(一) 2. 我终于弄懂了Python的装璜器(二) 3. 我终于弄懂了Python的装璜器(三) 4. 我终于弄懂了Python的装璜器(四) 对于将参数传递给装璜器自身,您怎么认为? 因为装璜器必须承受一个函数作为参数,所以这可能会有些顺当。 因而,您不能将装璜函数的参数间接传递给装璜器。 在寻求解决方案之前,让咱们写一些揭示: 后果一样。 毫不奇怪,跟咱们前边演示的内容一样。 让咱们再做一次齐全一样的事件,然而这次咱们跳过所有厌恶的两头变量: 让咱们把它变的更精简: 嘿,你看到了吗?咱们应用了带有“ 因而,回到带有参数的装璜器。 记住它:带参数的装璜器,能够将变量作为参数: 如您所见,您能够像任何函数传递参数一样传递参数给装璜器。二、装璜器的高级用法
将参数传递给装璜函数
#它不是黑魔法,只是给包装(wrapper)传递参数:def a_decorator_passing_arguments(function_to_decorate): def a_wrapper_accepting_arguments(arg1, arg2): print("I got args! Look: {0}, {1}".format(arg1, arg2)) function_to_decorate(arg1, arg2) return a_wrapper_accepting_arguments#因为当您调用装璜器返回的函数时,调用的包装器(wrapper),将参数传递给被包装器包装的函数@a_decorator_passing_argumentsdef print_full_name(first_name, last_name): print("My name is {0} {1}".format(first_name, last_name))print_full_name("Peter", "Venkman")# 输入:#I got args! Look: Peter Venkman#My name is Peter Venkman
将参数传递给装璜器
#装璜器是一般函数def my_decorator(func): print("I am an ordinary function") def wrapper(): print("I am function returned by the decorator") func() return wrapper# 因而,你能够调用它,而不必 "@"def lazy_function(): print("zzzzzzzz")decorated_function = my_decorator(lazy_function)#输入: I am an ordinary function# 它输入了 "I am an ordinary function", 因为你只是调用了装璜器,而没有调用函数:# 这里没有什么神奇的中央,应用'@'@my_decoratordef lazy_function(): print("zzzzzzzz")#outputs: I am an ordinary function
my_decorator
”被调用了。
因而,当您应用时@my_decorator
,您要通知Python,通过变量来调用
my_decorator
标记了的函数。
def decorator_maker(): print("I make decorators! I am executed only once: " "when you make me create a decorator.") def my_decorator(func): print("I am a decorator! I am executed only when you decorate a function.") def wrapped(): print("I am the wrapper around the decorated function. " "I am called when you call the decorated function. " "As the wrapper, I return the RESULT of the decorated function.") return func() print("As the decorator, I return the wrapped function.") return wrapped print("As a decorator maker, I return a decorator") return my_decorator#让咱们新建一个装璜器new_decorator = decorator_maker() #输入:#I make decorators! I am executed only once: when you make me create a decorator.#As a decorator maker, I return a decorator# 让咱们装璜这个函数def decorated_function(): print("I am the decorated function.")decorated_function = new_decorator(decorated_function)#输入:#I am a decorator! I am executed only when you decorate a function.#As the decorator, I return the wrapped function# 让咱们调用这个函数decorated_function()#输入:#I am the wrapper around the decorated function. I am called when you call the decorated function.#As the wrapper, I return the RESULT of the decorated function.#I am the decorated function.
def decorated_function(): print("I am the decorated function.")decorated_function = decorator_maker()(decorated_function)#输入:#I make decorators! I am executed only once: when you make me create a decorator.#As a decorator maker, I return a decorator#I am a decorator! I am executed only when you decorate a function.#As the decorator, I return the wrapped function.# Finally:decorated_function() #输入:#I am the wrapper around the decorated function. I am called when you call the decorated function.#As the wrapper, I return the RESULT of the decorated function.#I am the decorated function.
@decorator_maker()def decorated_function(): print("I am the decorated function.")#输入:#I make decorators! I am executed only once: when you make me create a decorator.#As a decorator maker, I return a decorator#I am a decorator! I am executed only when you decorate a function.#As the decorator, I return the wrapped function.#最终: decorated_function() #输入:#I am the wrapper around the decorated function. I am called when you call the decorated function.#As the wrapper, I return the RESULT of the decorated function.#I am the decorated function.
@
”语法的函数调用!
如果咱们能够应用函数即时生成装璜器,则能够将参数传递给该函数,对吗?def decorator_maker_with_arguments(decorator_arg1, decorator_arg2): print("I make decorators! And I accept arguments: {0}, {1}".format(decorator_arg1, decorator_arg2)) def my_decorator(func): #这里传递的参数是闭包的。 #如果您对封包感到不难受,能够疏忽这点。 print("I am the decorator. Somehow you passed me arguments: {0}, {1}".format(decorator_arg1, decorator_arg2)) #不要混同装璜器参数和函数参数! def wrapped(function_arg1, function_arg2) : print("I am the wrapper around the decorated function.\n" "I can access all the variables\n" "\t- from the decorator: {0} {1}\n" "\t- from the function call: {2} {3}\n" "Then I can pass them to the decorated function" .format(decorator_arg1, decorator_arg2, function_arg1, function_arg2)) return func(function_arg1, function_arg2) return wrapped return my_decorator@decorator_maker_with_arguments("Leonard", "Sheldon")def decorated_function_with_arguments(function_arg1, function_arg2): print("I am the decorated function and only knows about my arguments: {0}" " {1}".format(function_arg1, function_arg2))decorated_function_with_arguments("Rajesh", "Howard")#输入:#I make decorators! And I accept arguments: Leonard Sheldon#I am the decorator. Somehow you passed me arguments: Leonard Sheldon#I am the wrapper around the decorated function. #I can access all the variables # - from the decorator: Leonard Sheldon # - from the function call: Rajesh Howard #Then I can pass them to the decorated function#I am the decorated function and only knows about my arguments: Rajesh Howard
c1 = "Penny"c2 = "Leslie"@decorator_maker_with_arguments("Leonard", c1)def decorated_function_with_arguments(function_arg1, function_arg2): print("I am the decorated function and only knows about my arguments:" " {0} {1}".format(function_arg1, function_arg2))decorated_function_with_arguments(c2, "Howard")#输入:#I make decorators! And I accept arguments: Leonard Penny#I am the decorator. Somehow you passed me arguments: Leonard Penny#I am the wrapper around the decorated function. #I can access all the variables # - from the decorator: Leonard Penny # - from the function call: Leslie Howard #Then I can pass them to the decorated function#I am the decorated function and only know about my arguments: Leslie Howard
您甚至能够依据须要应用*args, **kwargs
。
然而请记住,装璜器仅被调用一次,仅在Python导入脚本时。之后,您将无奈动静设置参数。
当您执行“ import x”时,该函数曾经被润饰,因而您无奈进行任何更改。本文首发于BigYoung小站