我试图编写python装饰器,但在理解内部包装器如何接受参数时遇到了问题。我这里有:
import time
def timing_function(some_function):
def wrapper():
t1 = time.time()
some_function()
t2 = time.time()
return "Time it took to run: " + str((t2-t1)) + "\n"
return wrapper
@timing_function
def my_function(x):
return x * x
my_function(6)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-fe2786a2753c> in <module>()
----> 1 my_function(6)
TypeError: wrapper() takes no arguments (1 given)
与示例略有不同:
import time
def timing_function(some_function):
"""
Outputs the time a function takes
to execute.
"""
def wrapper():
t1 = time.time()
some_function()
t2 = time.time()
return "Time it took to run the function: " + str((t2-t1)) + "\n"
return wrapper
@timing_function
def my_function():
num_list = []
for x in (range(0,10000)):
num_list.append(x)
return "\nSum of all the numbers: " +str((sum(num_list)))
print my_function()
Time it took to run the function: 0.0
似乎问题出在“x”参数上。我试着给出包装器*参数,但也没用。我的问题是
在这个简单的包装器中允许参数的正确方法是什么?谢谢
为什么我看到的所有decorator示例都有一个内部函数,您不能将decorator编写为一个函数吗?
谢谢你
您需要将arg添加到wrapper,然后添加一些函数:
如果要在不同的函数上使用decorator,请使用*args和**kwargs,这也适用于不带参数的函数:
另一方面,如果您想计时代码,您可能会发现timeit模块很有用,如果您安装了ipython,您可以简单地使用
timeit your_function
。为什么我看到的所有decorator示例都有一个内部函数,您不能将decorator编写为一个函数吗?
不,Python中的decorator是一个可调用的Python对象,用于修改函数、方法或类定义。原始对象(将要修改的对象)作为参数传递给decorator。decorator返回一个修改过的对象,例如一个修改过的函数,它被绑定到定义中使用的名称,这里有更多的例子here
您需要将参数从
my_function
传递到wrapper
,即:如果您希望它能够一般地处理更多的函数,那么您必须执行以下操作:
但是,decorator中的逻辑还需要能够泛型地处理
args
和kwargs
。因为decorator是一个函数,它接受一个函数作为参数并返回一个作为原始函数包装器执行的函数。实际上,decorator通常被写成三个函数:
为什么这么做?您可以根据要装饰的函数类型,或者装饰器的不同行为方式,将一些信息传递给装饰器。
在Python解释器中,
functools.wraps
将使修饰后的函数看起来像原始函数。这有助于日志记录和调试等,也是创建装饰器时使用的最佳实践。相关问题 更多 >
编程相关推荐