闭包与装饰器函数类型为Nonetype
import timedef time_master(msg):
def call_func(func):
print("开始运行程序...")
start = time.time()
func()
stop = time.time()
print("结束程序运行...")
print(f"[{msg}]一共耗费了{(stop - start):.2f}秒。")
return
return call_func
@time_master('你好')
def myfunc():
time.sleep(2)
print("I Love FichC ^o^")
print(myfunc.__name__)请问一下,为什么现在的myfunc类型是一个nonetype啊
在这个示例中,您使用了装饰器函数@time_master('你好')来装饰myfunc()函数。装饰器函数的作用是在不修改被装饰函数源代码的情况下,为其添加额外的功能。
在您的代码中,time_master()函数返回了内部定义的函数call_func(),并且call_func()函数被装饰器应用到myfunc()上。当装饰器应用后,原本的myfunc()函数已经被call_func()函数替代了,因此调用myfunc()实际上会执行call_func()函数的逻辑。
由于call_func()函数没有明确的返回值,它的返回类型默认为NoneType,所以经过装饰后的myfunc()函数也会返回NoneType。
如果您希望保留myfunc()的原始类型,可以在call_func()函数中添加一个return func语句,将原始函数返回。这样,myfunc()函数的类型将与原始函数类型相同。例如:
def time_master(msg):
def call_func(func):
print("开始运行程序...")
start = time.time()
func()
stop = time.time()
print("结束程序运行...")
print(f"[{msg}]一共耗费了{(stop - start):.2f}秒。")
return func# 添加此行
return call_func
@time_master('你好')
def myfunc():
time.sleep(2)
print("I Love FichC ^o^")
print(myfunc.__name__)# 输出:myfunc
通过添加return func语句,您可以保留原始函数的类型。
如果问题已经解决,请设置最佳答案 在这个代码中,出现 myfunc 类型为 NoneType 的问题是因为装饰器函数 time_master 没有正确返回内部函数 call_func 的引用。
让我们来分析代码的执行过程:
1. 定义了 time_master 装饰器函数,它接受一个 msg 参数,并返回一个内部函数 call_func 。
2. 在定义 myfunc 函数之前,使用 @time_master('你好') 语法将 myfunc 函数装饰了起来。这相当于执行了 myfunc = time_master('你好')(myfunc) ,即用 time_master('你好') 返回的函数对象来重新绑定 myfunc 变量。
3.call_func 内部函数在被调用时会执行传入的函数 func() ,在这里就是 myfunc() 。
4.myfunc 函数内部执行了 time.sleep(2) 来模拟耗时操作,然后打印一条消息。
然而, call_func 内部没有返回任何值,而是直接使用了 func() 执行了 myfunc() 函数。因为 myfunc 函数本身没有返回值,所以 call_func 内部的 return 语句实际上返回了默认值 None ,导致 myfunc 函数被装饰后,其类型变为 NoneType 。
为了解决这个问题,你需要在 call_func 内部添加一个返回语句,将 func() 的返回值传递给外部调用。修改代码如下:
import time
def time_master(msg):
def call_func(func):
print("开始运行程序...")
start = time.time()
result = func()# 调用func,并获取其返回值
stop = time.time()
print("结束程序运行...")
print(f"[{msg}]一共耗费了{(stop - start):.2f}秒。")
return result# 返回func的返回值
return call_func
@time_master('你好')
def myfunc():
time.sleep(2)
print("I Love FichC ^o^")
print(myfunc.__name__)
现在, myfunc 应该会被正确地装饰,并且其类型不再是 NoneType ,而是一个函数类型。 报错了呀
开始运行程序...
I Love FichC ^o^
结束程序运行...
[你好]一共耗费了2.01秒。
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In, line 20
17 time.sleep(2)
18 print("I Love FichC ^o^")
---> 20 print(myfunc.__name__)
AttributeError: 'NoneType' object has no attribute '__name__' 歌者文明清理员 发表于 2023-7-28 16:53
报错了呀
对啊,因为这个时候的myfunc类型是一个NoneType类型,所以它会报错,但是现在我知道问题在哪里了{:10_256:} isdkz 发表于 2023-7-28 16:50
在这个代码中,出现 myfunc 类型为 NoneType 的问题是因为装饰器函数 time_master 没有正确返回内部函数 ca ...
厉害,return restult中restult是什么啊?python内置的吗?我昨天想的是直接return func. 松V溪 发表于 2023-7-29 14:27
厉害,return restult中restult是什么啊?python内置的吗?我昨天想的是直接return func.
result 就是 func 调用的返回值呀,我把 func() 赋值给 result 了 松V溪 发表于 2023-7-29 14:24
对啊,因为这个时候的myfunc类型是一个NoneType类型,所以它会报错,但是现在我知道问题在哪里了{:10_256 ...
这个表情……{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:}{:10_256:} isdkz 发表于 2023-7-29 14:29
result 就是 func 调用的返回值呀,我把 func() 赋值给 result 了
okk,感谢,我当时没看前面{:10_266:}
页:
[1]