我有一个装饰器函数my_fun(I,k)
,它会应用于函数add(x,y)
@my_fun(4,5)
def add(x,y): return x+y
我是Python的新手想知道我是否正在编写my_fun
函数
x,y
?my_fun
我对语法和概念有点困惑,任何解释都会有所帮助。
答案 0 :(得分:2)
装饰器由装饰器函数和函数包装器组成(如果你想要装饰器的另外一个参数,那么它周围的另一个外层函数):
# Takes the arguments for the decorator and makes them accessible inside
def my_fun(decorator_argument1, decorator_argument2):
# Takes the function so that it can be wrapped.
def wrapfunc(func):
# Here we are actually going to wrap the function ... finally
def wrapper(*args, **kwargs):
# Call the function with the args and kwargs
res = func(*args, **kwargs)
# return this result
return res
# Replace the decorated function with the wrapper
return wrapper
# Return the wrapper for the function wrapper :-)
return wrapfunc
在您的情况下,如果您只想将装饰器与您的功能一起使用,则无需使用*args, **kwargs
并将其替换为:
def wrapper(x, y):
# Here you can do stuff with x and y, i.e. print(x)
# Call the function with x and y
res = func(x, y)
# Here you can do stuff with the result, i.e. res = res * decorator_argument1
return res
我指出了您可以访问x
和y
的位置以及结果。
如果要预定义x
和y
的值,自定义装饰器不是最好的方法。您可以使用默认值:
def add(x=4,y=5): return x+y
add() # returns 9
add(2) # returns 7
add(5, 10) # returns 15
或者如果您想修复参数,则应使用functools.partial
答案 1 :(得分:0)
如果您使用@my_fun(4, 5)
将参数传递给装饰器,则需要三级嵌套函数以最简单的方式实现装饰器。外层是“装饰工厂”。它返回中间级函数,装饰器。装饰器使用它作为参数装饰的函数调用,并且需要返回内部最嵌套的函数,即包装器。包装函数是用户调用的函数。
def decorator_factory(deco_arg, deco_arg2): # name this whatever you want to use with @syntax
def decorator(func):
def wrapper(func_arg, func_arg2):
# This is a closure!
# In here you can write code using the arguments from the enclosing scpoes. e.g.:
return func(func_arg*deco_arg, func_arg2*deco_arg2) # uses args from all levels
return wrapper
return decorator
这里的内部功能是闭包。即使在这些范围所属的函数已经完成运行之后,它们也可以看到它们所定位的范围内的变量。
(注意,如果您希望装饰器能够装饰许多不同的功能,您可能希望wrapper
功能接受*args
和**kwargs
并将它们传递给{{ 1}}。上面的例子仅适用于接受两个参数的函数。对于某些用途,这样的限制可能是完全合理的,但并非总是如此。)