patrickcui 发表于 2022-12-15 10:50:29

Python装饰器的理解

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!

tommyyu 发表于 2022-12-15 10:55:16

加一对小括号不就是执行func这个函数么,此处func应该是一个函数传入,func()就是执行这个函数,就比如print()就是执行print函数

patrickcui 发表于 2022-12-15 11:06:34

tommyyu 发表于 2022-12-15 10:55
加一对小括号不就是执行func这个函数么,此处func应该是一个函数传入,func()就是执行这个函数,就比如prin ...

那你的意思是传入一个函数?那不是应该这么写吗?def timeslong(func()):而不是def timeslong(func):

tommyyu 发表于 2022-12-15 11:08:35

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

加小括号是调用函数,不加小括号代表这个函数本身。

patrickcui 发表于 2022-12-15 11:14:00

tommyyu 发表于 2022-12-15 11:08
加小括号是调用函数,不加小括号代表这个函数本身。

好像有点理解了!加()是使用这个函数,而不加()就是指代这个函数是哪一个?是这么理解吗?

tommyyu 发表于 2022-12-15 11:15:52

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

是的

最是无情读书人 发表于 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()这三是一个东西,函数地址

最是无情读书人 发表于 2022-12-15 11:16:43

myfunc   func func()这三是一个东西,函数地址

patrickcui 发表于 2022-12-15 11:21:34

tommyyu 发表于 2022-12-15 11:15
是的

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())

tommyyu 发表于 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)

patrickcui 发表于 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函数进行嵌套将非函数类型的返回值转变为函数类型的返回值并返回??

tommyyu 发表于 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)即可。

阿奇_o 发表于 2022-12-15 15:07:02

本帖最后由 阿奇_o 于 2022-12-15 15:08 编辑

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

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

倘若你自己搜搜练练、琢磨琢磨、理解了这三句话,以后关于什么装饰器、什么函数或方法的 80%的问题,你都可以自己搞清楚。
{:10_279:}
页: [1]
查看完整版本: Python装饰器的理解