笑星星 发表于 2024-1-24 22:15:38

运行结果不同

#first
def func1():
    print('ddddddd')
def outer(func):
    def inner():
      print('****')
      func()
    return inner
f = outer(func1)
f()

#second
def outer(func):
    def inner(*args,**kwargs):
                print('*' *50)
      return func(*args,**kwargs)
    return inner
@outer
def say(name,age):   
    print('my name is %s, I am %d years old ' % (name,age))
    return 'aaaa'
# say('sunck',19)   #单独选择此行或下一行执行没有错误
l = say('sunck',19)
l()                #联合选择此行及上一有错误,为啥不需要此行
#为啥好像是同样的格式 f()可以运行,l()不能

FishC 发表于 2024-1-24 22:16:45

在第一个例子中,您创建了一个装饰器函数outer,它接受一个函数作为参数,并返回一个新的函数inner。在inner函数内部,您打印了一条分隔线,然后调用传入的函数func。最后,您将outer应用到func1函数上,并将结果赋给变量f。当您调用f()时,实际上是调用了inner函数,inner函数又调用了func1函数。

在第二个例子中,您定义了一个装饰器函数outer,与第一个例子中类似,但有一点不同。在outer函数内部,您定义了一个带有*args和**kwargs参数的inner函数。这样,inner函数可以接受任意数量的位置参数和关键字参数。在inner函数内部,您打印了一条分隔线,并通过使用*args和**kwargs将这些参数传递给传入的函数func。最后,您将outer应用到say函数上,并将结果赋给变量l。当您调用l()时,实际上是调用了inner函数。

那么为什么f()可以运行而l()不能呢?这是因为在第一个例子中,outer函数返回的是inner函数本身,因此当您调用f()时,实际上是调用了inner函数。而在第二个例子中,outer函数返回的是inner函数的引用,并没有执行inner函数。所以当您调用l()时,实际上是尝试调用inner函数的引用,而不是inner函数本身,所以会出现错误。

为了解决这个问题,您可以将第二个例子中的最后一行代码修改为l,即不使用括号调用l。这样,您就可以正确地输出结果了。也就是说,l是一个函数的引用,而不是函数本身,所以不需要使用括号进行调用。

修正后的代码如下:

def outer(func):
    def inner(*args, **kwargs):
      print('*' * 50)
      return func(*args, **kwargs)
    return inner

@outer
def say(name, age):   
    print('my name is %s, I am %d years old ' % (name,age))
    return 'aaaa'

# say('sunck',19)   # 单独选择此行或下一行执行没有错误
l = say('sunck', 19)
l                # 联合选择此行及上一行没有错误

希望以上解释和代码示例能够帮助您理解并解决问题。如果还有其他疑问,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

jackz007 发表于 2024-1-24 23:29:51

本帖最后由 jackz007 于 2024-1-24 23:57 编辑

      first 是一个闭包
#first
def outer(func):
    def inner():
. . . . . .
    return inner                        # 因为函数 outer() 返回的是 内嵌函数 inner() 的调用句柄。
. . . . . .
f = outer()                           # 变量 f 接收到内嵌函数的调用句柄
f()                                     # 调用 outer() 的内嵌函数 inner()

      second 是一个装饰器
#second
def outer(func):                        # 函数 outer() 用于对函数 say() 进行装饰器包装,以便在 say() 被调用的时候获得控制
    def inner(*args,**kwargs):          # 当对 say(* args , ** kwargs) 进行调用时,实际上是 outer() 的内嵌函数 inner(* args , ** kwargs) 被调用
      print('*' *50)                # 先连续打印 50 个 '*'               
      return func(*args,**kwargs)   # 再返回对被装饰函数 say(* args , ** kwargs) 的调用结果
    return inner

@outer                                  # 声明函数 say() 被 outer() 函数装饰,此后,凡是对 say() 函数的调用都转向到对 outer()
                                        # 的内嵌函数 inner() 的调用,并在 inner() 中完成对被装饰函数 say() 的调用
def say(name,age):   
    print('my name is %s, I am %d years old ' % (name,age))
    return 'aaaa'
# say('sunck',19)
l = say('sunck',19)                     # 实际调用的是 inner('sunck' , 19)
                                        # 先执行 print('*' * 50)
                                        # 再返回对函数 say('sunck' , 19) 的调用结果
          二者是完全不同的两个概念,所以,二者的运行结果毫无可比性,这是正常的结果。
页: [1]
查看完整版本: 运行结果不同