因为装饰器必须接收一个函数当做参数,所以不可以直接把被装饰函数的参数传递给装饰器.
装饰器就是一个普通的函数,回顾
def my_decorator(func):
print("I am an ordinary function")
def wrapper():
print("I am function returned by thedecorator")
func()
return wrapper
因此,同样可以像普通函数一样调用装饰器,而不用@
def lazy_function():
print("zzzzz")
调用,
decorated_function =my_decorator(lazy_function) ##后面加()就会输出整个装饰完的结果
输出
I am an ordinaryfunction
执行下面的代码段:
@my_decorator
def lazy_function():
print("zzzzz")
同样输出
I am an ordinaryfunction
和"my_decorator"一样只是被调用.所以当你用@my_decorator你只是告诉Python去掉用被变量my_decorator标记的函数.并没有调用要装饰的函数。
切记:标记能直接指向装饰器.
再看下面的例子:
def decorator_maker():
print("I make decorators! I am excuted only once:whenyou make me create a decorator.")
def my_decorator(func):
print("I am a decorator! I am executed only whenyou decorate a function.")
def wrapped():
print("I am the wrapper around the decoratedfunction.I am called when you callthe decorated function,As the wrapper, I return the result of the decoratedfunction!")
return func()
print("As the decorator,I return the wrappedfunction")
return wrapped
print("Asthe decorator maker , I return a decorator")
return my_decorator
建一个装饰器,它只是一个新函数
new_decorator =decorator_maker() #返回一个装饰器函数
输出
#I make decorators! Iam 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")
decoration_function =new_decorator(decorated_function) #decorator_maker返回了装饰器函数,这里加上括号及参数相当于调用了装饰器函数,执行了my_decorator(func),并未装饰,返回装饰器,就像本文开始的调用一样。
输出
#I am a decorator! Iam executed only when you decorate a function.
#As the decorator, I return the wrapped function
下面执行装饰器函数
decoration_function() #上面的装饰器函数返回了装饰器,这里加上括号才执行了装饰器
输出
#I am the wrapperaround the decorated function. I am called when you call the decoratedfunction.
#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 onlyonce: when you make me create a decorator.
#As a decorator maker, I return a decorator
#I am a decorator! I am executed only whenyou decorate a function.
#As the decorator, I return the wrappedfunction.
最后再次调用得到的函数
decorated_function()
输出
#I am the wrapper around the decoratedfunction. I am called when you call the decorated function.
#As the wrapper, I return the RESULT of thedecorated function.
#I am the decorated function.
简化一下:
@decorator_maker() ###加括号的
def decorated_function():
print("Iam the decorated_function")
执行上述代码段,输出
#I make decorators! I am executed onlyonce: when you make me create a decorator.
#As a decorator maker, I return a decorator
#I am a decorator! I am executed only whenyou decorate a function.
#As the decorator, I return the wrappedfunction.
最终,执行
decorated_function()
输出
#I am the wrapper around the decoratedfunction. I am called when you call the decorated function.
#As the wrapper, I return the RESULT of thedecorated function.
#I am the decorated function.
所以装饰器的参数问题可以通过上述思路解决!
def decorator_maker_arguments(decorator_arg1,decorator_arg2):
print("Imake decorators!And I accept argument:",decorator_arg1,decorator_arg2)
def my_decorator(func):
# 这里传递参数的能力是借鉴了 closures.
# 如果对closures感到困惑可以看看下面这个:
#http://stackoverflow.com/questions/13857/can-you-explain-closures-as-they-relate-to-python
print("Iam the decorator. somehow you pass me arguments:",decorator_arg1,decorator_arg2)
# 不要忘了装饰器参数和函数参数!
def wrapped(function_arg1,function_arg2):
print("Iam the wrapper around the decorated function.\nI can access all thevariables\n\t-fromthe decorator:{0}{1}\n\t-fromthe function call:{2}{3}\nThen 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_arguments("Leonard","Sheldon")
defdecorated_function_with_arguments(function_arg1,function_arg2):
print("I am the decoratedfunction 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 mearguments: Leonard Sheldon
#I am the wrapper around the decoratedfunction.
#I can access all the variables
# - from thedecorator: Leonard Sheldon
# - from the functioncall: Rajesh Howard
#Then I can pass them tothe decorated function
#I am the decorated function and only knows about my arguments: Rajesh Howard
上面就是带参数的装饰器.参数可以设置成变量:
c1 = "Penny"
c2 = "Leslie"
@decorator_maker_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 mearguments: Leonard Penny
#I am the wrapper around the decoratedfunction.
#I can access all the variables
# -from the decorator: Leonard Penny
# -from the function call: Leslie Howard
#Then I can pass them to the decoratedfunction
#I am the decorated function and only knowsabout my arguments: Leslie Howard
可以用这种方式把任何函数的参数传递给装饰器.还可以用*args,**kwargs.
但是一定要记住了装饰器只能被调用一次.
当Python载入脚本后,就不可以动态的设置参数了.当你运行import x,函数已经被装饰,所以你什么都不能动了.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)