在 Python3 中创建装饰器时出现问题
Issue creating decorator in 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 decorated_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 decorated_function(function_arg1, function_arg2):
print("Hello {0} {1}".format(function_arg1, function_arg2))
decorated_function("宇宙与","一切")
虽然您可以在另一个没有 return 任何可调用对象的 单个 函数中包装和运行,但请记住,包装后的函数不再可调用。因此,当计时对象不需要原始对象的可重用性时,您当前的代码有效:
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 (most recent call last):
File "", line 1, in
TypeError: 'NoneType' object is not callable
为防止上述错误,在装饰函数中创建一个包装函数:
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
谁能告诉我我犯了什么错误。
装饰器
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 decorated_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 decorated_function(function_arg1, function_arg2):
print("Hello {0} {1}".format(function_arg1, function_arg2))
decorated_function("宇宙与","一切")
虽然您可以在另一个没有 return 任何可调用对象的 单个 函数中包装和运行,但请记住,包装后的函数不再可调用。因此,当计时对象不需要原始对象的可重用性时,您当前的代码有效:
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 (most recent call last): File "", line 1, in TypeError: 'NoneType' object is not callable
为防止上述错误,在装饰函数中创建一个包装函数:
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