星夕ING 发表于 2022-11-22 10:11:06

046讲装饰器相关问题

小甲鱼046讲布置到延长输出结果时间的一道题,要求修改以下代码,使其一秒钟输出一个结果,原代码如下:
import time
   
def fib():
    back1, back2 = 0, 1
    def func():
      nonlocal back1, back2
      back1, back2 = back2, back1 + back2
      print(back1, end=' ')
    return func
   
def get_fib(n):
    f = fib()
    for i in range(n):
      f()
   
n = int(input("请输入需要获取的斐波那契数:"))
get_fib(n)



添加延长时间的代码只需要time.sleep(1)就可以了
我们在前面加一个代码:
def delay(func):
   def call_func():
          time.sleep(1)
          func()
    return call_func

然后,小甲鱼在def func()的位置写了@dalay
我尝试着在def fib()那里写@delay,python报错了,告诉我当它试图call func()的时候,发现func是none type因此不能call
为什么会这样?所以说如果是嵌套函数,必须得是内部函数才可以用装饰器吗?
提前感谢大佬们解答!!!!

星夕ING 发表于 2022-11-22 10:15:18

对不起家人们!不是在call func()的时候报错,是在f=fib()那里报错了QAQ,期待解答

lxping 发表于 2022-11-22 10:26:18

星夕ING 发表于 2022-11-22 10:15
对不起家人们!不是在call func()的时候报错,是在f=fib()那里报错了QAQ,期待解答

将 print(back1, end=' ')改成 return back1 试一下

jackz007 发表于 2022-11-22 11:03:06

本帖最后由 jackz007 于 2022-11-22 11:36 编辑

      之所以不能装饰 fib() 那是因为 fib() 不是一个正常函数,而是一个闭包,不会被多次调用,也不会返回我们想要的数列元素,装饰这个函数无法满足每秒输出 1 个数的要求,只要把函数 fib() 改写为正常函数就可以解决问题。
import time

def delay(func):
   def call_func(* args):
          time . sleep(1)
          return func(* args)
   return call_func

@delay
def fib(n):
    b = 0
    if n >= 0:
      a = b = 1
      for _ in range(2 , n) : a , b = b , a + b
    return b

def get_fib(n):
    for i in range(1 , n + 1):
      print(fib(i))
   
n = int(input("请输入需要获取的斐波那契数:"))
get_fib(n)
页: [1]
查看完整版本: 046讲装饰器相关问题