鱼C论坛

 找回密码
 立即注册
查看: 838|回复: 2

运行结果不同

[复制链接]
发表于 2024-1-24 22:15:38 | 显示全部楼层 |阅读模式

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

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

x
#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()不能
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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) 的调用结果
          二者是完全不同的两个概念,所以,二者的运行结果毫无可比性,这是正常的结果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 19:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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