鱼C论坛

 找回密码
 立即注册
查看: 2106|回复: 8

[已解决]python闭包返回值为函数名称和函数名称加括号的时候有什么区别

[复制链接]
发表于 2020-10-14 09:27:14 | 显示全部楼层 |阅读模式

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

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

x
各位大神,本人在做课后作业的时候,遇到一个问题想不通。如以下两段代码
  代码1:
def funOut():
    def funIn():
        print('宾果!你成功访问到我啦!')
    return funIn()

代码2:

def funOut():
    def funIn():
        print('宾果!你成功访问到我啦!')
    return funIn


这两段代码中 return funIn() 和return funIn 有什么区别呢?
最佳答案
2020-10-14 21:06:00
这个问题几句话说不清楚.
我只能简单的说一下.
def func(x,y):
    print(x,y)
我们随便定义一个函数,这个函数的用途就是打印我们传入的两个位置参数x 和 y
这没什么好说的.你一定知道这个函数的意思.
但是想要实现这个功能,我们不能光是简单的定义函数,还要取调用函数
func(1, 2)    # 只有这样才能看到打印   (x = 1 y = 2 下文同理)

res = func(1, 2)    # 这个应该也很好理解吧.就是获取了 func的返回值 然后把这个返回值赋值给了res
print(res)        # 这里因该是输出None,因为func我们并没有定义返回值,所以默认返回None

然后我们在把代码改一下.建议你自己上机测试一下
res_1 = func    # 请注意我没有写括号
print(res_1)      # 你觉得这里会输出什么??????
其实这里是做了一个赋值操作.也就是把函数func的内存地址给了res_1    请注意是函数的内存地址 不是运行函数 也不是获取函数的返回值 仅仅是函数的内存地址
然后我们这么写
res_1(1, 2)          # 这里是把那个内存地址加上括号,就相当于执行了这个函数   
也就是说现在 res_1() 和func() 是一摸一样的.都是执行的func这个函数

同理
fanhuizhi = res_1(1, 2)    # 这里也是获取了func这个函数的返回值
print(fanhuizhi)        # 这里应该是None

这些是函数对象当中的部分知识.简单来说就是把函数的内存地址直接拿来用.而不是调用函数本身.

还有一个简单的例子
def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")

如果我仅仅是这么写,那么请问你有办法调用到f2函数吗???
f2()    # 这么写会报错.因为在全局作用域当中找不到f2   f2 是 f1 里面的函数,所以f2 的作用域应该是在f1 当中.
也就是说;我们无法通过全局作用域访问到局部作用域当中的函数
但是;假如我们非要这个函数不可.那么我们可以这么改
def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")
    return f2    # 请注意;千万不要加括号,这里是把f2的内存地址给返回了.仅仅是内存地址

res = f1()    # 这时候的res 就拿到了f2的内存地址
res()          # 拿到了内存地址当然就可以直接用喽, 因为这个内存地址是一个函数的内存地址,那么只要在这个内存地址的后面加上()就可以执行这个函数了
这样的操作就实现了,从全局作用域访问局部作用域中的函数的目的.
当然;如果f2有返回值的话你同样可以访问的到

def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")
            return 123
    return f2

res = f1()   # 拿到f2的内存地址,赋值给res
fanhuizhi = res()    # 调用res()就相当于调用f2()  这样就拿到了f2的返回值



主要的用途在于装饰器啊,当你学到装饰器就知道了.



顺带提一下刚才的代码.
def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")
            return 123
    return f2

res = f1()    # 这里是拿到了f2的内存地址赋值给res 内存地址只是一个数据而已.这里数据可以给任何一个变量名
res1 = f1()
neicun_dizhi = f1()
hahahahah = f1()   # 这么写没有任何问题.变量名你i可以随便取.既然如此,当然也可以叫f2
f2 = f1()    # 获取f2的内存地址赋值给f2这个变量
f2()     # 调用f2这个函数...............这样是不是直接调用了f2 这个函数???????
但是;请注意这里的f2是在全局作用域,它和那个我们定义的f2的作用域是不同的.....................
具体的请百度或者看小甲鱼之后的视频...

评分

参与人数 1荣誉 +5 鱼币 +4 贡献 +3 收起 理由
shmily。lady + 5 + 4 + 3

查看全部评分

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

使用道具 举报

发表于 2020-10-14 10:24:18 | 显示全部楼层
funIn() 返回的是方法的return返回值
funIn  返回的方法对象
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-14 14:41:06 | 显示全部楼层

假设你写了个运行多个任务的函数 它接受的每个任务也都是一个个函数
def do(*tasks):
    for task in tasks:
        if callable(task):
            task()
现在你要写两个任务给它运行 一个是time.sleep(?),另一个是print(?)
你现在就得定义两个任务
def sleepOut(s):
    def sleepIn():
        time.sleep(s)
    return sleepIn

def printOut(c):
    def printIn():
        print(c)
    return printIn
现在你有两个任务 睡眠5秒后打印我好了
只需要 do(sleepOut(5),printOut('我好了'))
现在你再想想 如果改成 return 函数名() 什么也做不了 他相当于 do(None,None)了


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

使用道具 举报

发表于 2020-10-14 21:05:04 | 显示全部楼层
函数名 + () 是调用这个函数 并且获取这个函数的返回值
函数名不加括号 是指的是这个函数的内存地址.
代码1 当中的return 返回的是函数funln() 这个函数的返回值
代码2 返回的是 funln 的内存地址
我记得上次我回答过这样的问题.等我把上次的回答复制一下.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-14 21:06:00 | 显示全部楼层    本楼为最佳答案   
这个问题几句话说不清楚.
我只能简单的说一下.
def func(x,y):
    print(x,y)
我们随便定义一个函数,这个函数的用途就是打印我们传入的两个位置参数x 和 y
这没什么好说的.你一定知道这个函数的意思.
但是想要实现这个功能,我们不能光是简单的定义函数,还要取调用函数
func(1, 2)    # 只有这样才能看到打印   (x = 1 y = 2 下文同理)

res = func(1, 2)    # 这个应该也很好理解吧.就是获取了 func的返回值 然后把这个返回值赋值给了res
print(res)        # 这里因该是输出None,因为func我们并没有定义返回值,所以默认返回None

然后我们在把代码改一下.建议你自己上机测试一下
res_1 = func    # 请注意我没有写括号
print(res_1)      # 你觉得这里会输出什么??????
其实这里是做了一个赋值操作.也就是把函数func的内存地址给了res_1    请注意是函数的内存地址 不是运行函数 也不是获取函数的返回值 仅仅是函数的内存地址
然后我们这么写
res_1(1, 2)          # 这里是把那个内存地址加上括号,就相当于执行了这个函数   
也就是说现在 res_1() 和func() 是一摸一样的.都是执行的func这个函数

同理
fanhuizhi = res_1(1, 2)    # 这里也是获取了func这个函数的返回值
print(fanhuizhi)        # 这里应该是None

这些是函数对象当中的部分知识.简单来说就是把函数的内存地址直接拿来用.而不是调用函数本身.

还有一个简单的例子
def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")

如果我仅仅是这么写,那么请问你有办法调用到f2函数吗???
f2()    # 这么写会报错.因为在全局作用域当中找不到f2   f2 是 f1 里面的函数,所以f2 的作用域应该是在f1 当中.
也就是说;我们无法通过全局作用域访问到局部作用域当中的函数
但是;假如我们非要这个函数不可.那么我们可以这么改
def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")
    return f2    # 请注意;千万不要加括号,这里是把f2的内存地址给返回了.仅仅是内存地址

res = f1()    # 这时候的res 就拿到了f2的内存地址
res()          # 拿到了内存地址当然就可以直接用喽, 因为这个内存地址是一个函数的内存地址,那么只要在这个内存地址的后面加上()就可以执行这个函数了
这样的操作就实现了,从全局作用域访问局部作用域中的函数的目的.
当然;如果f2有返回值的话你同样可以访问的到

def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")
            return 123
    return f2

res = f1()   # 拿到f2的内存地址,赋值给res
fanhuizhi = res()    # 调用res()就相当于调用f2()  这样就拿到了f2的返回值



主要的用途在于装饰器啊,当你学到装饰器就知道了.



顺带提一下刚才的代码.
def f1():
    print('这里是f1函数')
        def f2():
            print("这里是f2函数")
            return 123
    return f2

res = f1()    # 这里是拿到了f2的内存地址赋值给res 内存地址只是一个数据而已.这里数据可以给任何一个变量名
res1 = f1()
neicun_dizhi = f1()
hahahahah = f1()   # 这么写没有任何问题.变量名你i可以随便取.既然如此,当然也可以叫f2
f2 = f1()    # 获取f2的内存地址赋值给f2这个变量
f2()     # 调用f2这个函数...............这样是不是直接调用了f2 这个函数???????
但是;请注意这里的f2是在全局作用域,它和那个我们定义的f2的作用域是不同的.....................
具体的请百度或者看小甲鱼之后的视频...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-15 10:45:40 | 显示全部楼层
终于懂了,十分感谢!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-15 10:46:13 | 显示全部楼层
linke.zhanghu 发表于 2020-10-14 21:06
这个问题几句话说不清楚.
我只能简单的说一下.
def func(x,y):

终于懂了,十分感谢!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-15 10:47:29 | 显示全部楼层
kogawananari 发表于 2020-10-14 14:41
假设你写了个运行多个任务的函数 它接受的每个任务也都是一个个函数

现在你要写两个任务给 ...

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

使用道具 举报

 楼主| 发表于 2020-10-15 10:48:15 | 显示全部楼层
fall_bernana 发表于 2020-10-14 10:24
funIn() 返回的是方法的return返回值
funIn  返回的方法对象

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-18 07:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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