鱼C论坛

 找回密码
 立即注册
查看: 879|回复: 3

修饰符

[复制链接]
发表于 2019-5-22 13:05:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import time

def timeslong(func):
    def call():
        start = time.clock()
        print("It's time starting ! ")
        func()
        print("It's time ending ! ")
        end = time.clock()
        return "It's used : %s ." % (end - start)
    return call

@timeslong
def f():
    y = 0
    for i in range(10):
        y = y + i + 1
        print(y)
    return y

print(f())








def fun(func):
    print('1')
    func()
    print('3')
@fun
def f():
    print('2')


问题:为什么第二个会自动输出,第一个就不会呢,我把return改成print仍然不能自动输出?




小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-5-22 18:03:09 | 显示全部楼层
这个应该是涉及到装饰器的原理,试了一下,第一个注册的时候是返回一个函数,也就是说相当于运行了一次f=timeslong(),后面可以调用f()来运行timeslong返回的call函数。而第二个,是运行了一次,但是没返回,也就是说相当于运行了一次f = fun(),因为fun没有返回,所以当你想再次运行f的时候就会报错。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-22 18:49:22 | 显示全部楼层
第二个函数不是装饰器
@func 实际上会运行一次 func()
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-22 20:07:18 | 显示全部楼层
第一个是装饰器的正确写法,把f()函数进行了装饰,但不执行,只有你调用f()的时候,才会执行

第二个就只是个修饰符,修饰符有个特点就是只要程序运行到这里了,哪怕不调用被装饰的函数,@那个函数(装饰函数)也会执行。

但你可能想问,第一个在装饰的时候,不也应该把 timeslong() 这个函数执行一遍么?
其实是已经执行了的,但因为里面只有一个函数的定义,并没有执行call()那个函数,所以啥都没输出,你把装饰函数改成下面这样,即便不调用 f() 也能看到输出了
  1. def timeslong(func):
  2.     print("----test_1----")
  3.     def call():
  4.         start = time.clock()
  5.         print("It's time starting ! ")
  6.         func()
  7.         print("It's time ending ! ")
  8.         end = time.clock()
  9.         return "It's used : %s ." % (end - start)
  10.     print("----test_2----")
  11.     return call
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-1-15 23:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表