鱼C论坛

 找回密码
 立即注册
查看: 3267|回复: 12

[已解决]Python装饰器的理解

[复制链接]
发表于 2022-12-15 10:50:29 | 显示全部楼层 |阅读模式

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

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

x
import time

def timeslong(func):
    start = time.time()
    print("It's time starting ! ")
    func()#这是啥意思?func不是函数timeslong的一个形参吗?加一个()如何理解?
    print("It's time ending ! ")
    end = time.time()
    return "It's used : %s." % (end - start)

def myfunc():
    print("Hello FishC.")

t = timeslong(myfunc)


输出的结果:
It's time starting!
Hello FishC
It's time ending!

如果只写func
输出的结果:
It's time starting!
It's time ending!
最佳答案
2022-12-15 13:01:09
本帖最后由 tommyyu 于 2022-12-15 13:05 编辑
patrickcui 发表于 2022-12-15 12:40
还不是很理解!
@timeslong
def myfunc():


call函数是一个嵌套函数,也就是在函数中定义了一个函数,timeslong将这个函数作为返回值并返回。
将你的代码变为标准写法
def myfunc():
    print("Hello FishC.")
myfunc = timeslong(myfunc)
中,在执行第三行的语句时,myfunc 变成了 timeslong 函数的返回值,也就是 call 函数。因此,再执行 myfunc 时,执行的其实就是timeslong中定义的call函数,这就完成了对myfunc函数的加工

其实也可以不定义call函数,直接写
def myfunc():
    print("Hello FishC.")
timeslong(myfunc)
即可。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-12-15 10:55:16 | 显示全部楼层
加一对小括号不就是执行func这个函数么,此处func应该是一个函数传入,func()就是执行这个函数,就比如print()就是执行print函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-15 11:06:34 | 显示全部楼层
tommyyu 发表于 2022-12-15 10:55
加一对小括号不就是执行func这个函数么,此处func应该是一个函数传入,func()就是执行这个函数,就比如prin ...

那你的意思是传入一个函数?那不是应该这么写吗?def timeslong(func()):而不是def timeslong(func):
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-15 11:08:35 | 显示全部楼层
patrickcui 发表于 2022-12-15 11:06
那你的意思是传入一个函数?那不是应该这么写吗?def timeslong(func()):而不是def timeslong(func):

加小括号是调用函数,不加小括号代表这个函数本身。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-15 11:14:00 | 显示全部楼层
tommyyu 发表于 2022-12-15 11:08
加小括号是调用函数,不加小括号代表这个函数本身。

好像有点理解了!加()是使用这个函数,而不加()就是指代这个函数是哪一个?是这么理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-15 11:15:52 | 显示全部楼层
patrickcui 发表于 2022-12-15 11:14
好像有点理解了!加()是使用这个函数,而不加()就是指代这个函数是哪一个?是这么理解吗?

是的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-15 11:16:00 | 显示全部楼层
def timeslong(func):
    start = time.time()
    print("It's time starting ! ")
    func()#这是啥意思?func不是函数timeslong的一个形参吗?加一个()如何理解?
    print("It's time ending ! ")
    end = time.time()
    return "It's used : %s." % (end - start)

def myfunc():
    print("Hello FishC.")

t = timeslong(myfunc)



myfunc   func func()  这三是一个东西,函数地址
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-15 11:16:43 | 显示全部楼层
myfunc   func func()  这三是一个东西,函数地址
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-15 11:21:34 | 显示全部楼层


import time

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

@timeslong
def myfunc():
    print("Hello FishC.")

print(myfunc())


上面这段代码和下面这段代码区别在于timeslong函数里又套用了一个函数call,为什么要这么写?直接用下面的这个代码段不行吗?:
import time

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

@timeslong
def myfunc():
    print("Hello FishC.")

print(myfunc())
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-15 11:37:07 | 显示全部楼层
patrickcui 发表于 2022-12-15 11:21
import time

def timeslong(func):

装饰器的返回值应当是一个函数,这个函数是装饰器通过加工传入的函数实现的,这个call函数就相当于被加工后的函数。而
@timeslong
def myfunc():
    print("Hello FishC.")
相当于
def myfunc():
    print("Hello FishC.")
myfunc = timeslong(myfunc)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-15 12:40:49 | 显示全部楼层
tommyyu 发表于 2022-12-15 11:37
装饰器的返回值应当是一个函数,这个函数是装饰器通过加工传入的函数实现的,这个call函数就相当于被加工 ...

还不是很理解!
@timeslong
def myfunc():
    print("Hello FishC.")
程序执行的过程是将myfunc这个函数传给@装饰器后面的timeslong函数的func,接着因为call函数中没有形参,所以程序就直接进入到下一条语句,最后call函数得到一个非函数类型的返回值,又因为装饰器@必须要返回类型为函数类型所以就要在timeslong的函数体中加入call函数进行嵌套将非函数类型的返回值转变为函数类型的返回值并返回??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-15 13:01:09 | 显示全部楼层    本楼为最佳答案   
本帖最后由 tommyyu 于 2022-12-15 13:05 编辑
patrickcui 发表于 2022-12-15 12:40
还不是很理解!
@timeslong
def myfunc():


call函数是一个嵌套函数,也就是在函数中定义了一个函数,timeslong将这个函数作为返回值并返回。
将你的代码变为标准写法
def myfunc():
    print("Hello FishC.")
myfunc = timeslong(myfunc)
中,在执行第三行的语句时,myfunc 变成了 timeslong 函数的返回值,也就是 call 函数。因此,再执行 myfunc 时,执行的其实就是timeslong中定义的call函数,这就完成了对myfunc函数的加工

其实也可以不定义call函数,直接写
def myfunc():
    print("Hello FishC.")
timeslong(myfunc)
即可。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-15 15:07:02 | 显示全部楼层
本帖最后由 阿奇_o 于 2022-12-15 15:08 编辑

我看你骨骼惊奇,送你三句话:

在Python界,
    1. 函数,也是个 对象!?
    2. 函数,是个 "一等对象"。。???
    3. 函数,是个 可调用的对象 callable object ?

倘若你自己搜搜练练、琢磨琢磨、理解了这三句话,以后关于什么装饰器、什么函数或方法的 80%的问题,你都可以自己搞清楚。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-15 21:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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