python - 在 Python3 中创建装饰器的问题
问题描述
谁能让我知道我犯了什么错误。
装饰者
import time
def f1(f):
a = time.time()
f()
b = time.time()
c = b-a
print("time required is", c)
@f1
def f3(f2):
n = []
for i in range(1000):
n.append(i)
print(sum(n), "for F3")
f2()
@f3
def f4():
n = []
for i in range(1000):
n.append(i)
print(sum(n), "for F4")
f4
o/p:
回溯(最近一次通话最后):
File "C:/test.py", line 13, in <module>
@f1
File "C:/test.py", line 7, in f1
f()
TypeError: f3() missing 1 required positional argument: 'f2'
Process finished with exit code 1
希望实现这样的目标:
def decorator_with_args(decorator_to_enhance):
def decorator_maker(*args, **kwargs):
def decorator_wrapper(func):
return decorator_to_enhance(func, *args, **kwargs)
return decorator_wrapper
return decorator_maker
@decorator_with_args
def decorator(func, *args, **kwargs):
def wrapper(function_arg1, function_arg2):
print("Decorated with {0} {1}".format(args, kwargs))
return func(function_arg1, function_arg2)
return wrapper
@decorated_decorator(42, 404, 1024)
def 装饰函数(函数参数 1,函数参数 2):
print("Hello {0} {1}".format(function_arg1, function_arg2))
装饰函数(“宇宙和”,“一切”)
解决方案
虽然您可以在另一个不返回任何可调用对象的单个函数中包装和运行,但请记住,包装的函数不再是可调用的。因此,当对不需要原始对象可重用性的对象进行计时时,您当前的代码可以工作:
import time
def timeit(f):
c = time.time()
_ = f()
c2 = time.time()
print(f"'{f.__name__}' took {c2-c}s")
@timeit
def f2():
return sum(range(1000))
输出(不调用f2
):
'f2' took 8.988380432128906e-05s
但是,如果尝试调用f2
:
_ = f2()
Traceback(最近一次调用最后一次):文件“”,第 1 行,在 TypeError:'NoneType' 对象不可调用
为了防止上述错误,在装饰函数中创建一个包装函数:
def timeit(f):
def wrapper(*args, **kwargs):
c = time.time()
_result = f(*args, **kwargs)
c2 = time.time()
print(f"'{f.__name__}' took {c2-c}s")
return _result
return wrapper
@timeit
def f2():
return sum(range(1000))
f2
在被调用之前不会计时,触发wrapper
:
print(f2())
输出:
'f2' took 3.981590270996094e-05s
499500
推荐阅读
- c - c语言,全局符号,局部符号说明
- reactjs - 在 nginx 上隐藏上游 301 响应(反应应用程序)
- javascript - Lodash findKey() 方法
- redis - redis 是否提供了对缓存对象进行部分更新的选项
- typescript - 来自对象的所有嵌套值的类型
- javascript - 带有 javascript 标签的 Youtube iframe API
- django - 如何对特定字段求和
- flutter - Flutter 中的 3D 轮播动画
- button - 为什么我的 Button 样式对象仅适用于按钮内的文本,而不适用于整个按钮?
- docker - 在 Windows 上使用 docker-compose 增加 Docker 容器的内存?