bud 发表于 2020-10-14 09:27:14

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

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

代码2:

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


这两段代码中 return funIn() 和return funIn 有什么区别呢?

fall_bernana 发表于 2020-10-14 10:24:18

funIn() 返回的是方法的return返回值
funIn返回的方法对象

kogawananari 发表于 2020-10-14 14:41:06

{:10_289:}
假设你写了个运行多个任务的函数 它接受的每个任务也都是一个个函数
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)了


linke.zhanghu 发表于 2020-10-14 21:05:04

函数名 + () 是调用这个函数 并且获取这个函数的返回值
函数名不加括号 是指的是这个函数的内存地址.
代码1 当中的return 返回的是函数funln() 这个函数的返回值
代码2 返回的是 funln 的内存地址
我记得上次我回答过这样的问题.等我把上次的回答复制一下.

linke.zhanghu 发表于 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的作用域是不同的.....................
具体的请百度或者看小甲鱼之后的视频...

bud 发表于 2020-10-15 10:45:40

终于懂了,十分感谢!!

bud 发表于 2020-10-15 10:46:13

linke.zhanghu 发表于 2020-10-14 21:06
这个问题几句话说不清楚.
我只能简单的说一下.
def func(x,y):


终于懂了,十分感谢!!!

bud 发表于 2020-10-15 10:47:29

kogawananari 发表于 2020-10-14 14:41
假设你写了个运行多个任务的函数 它接受的每个任务也都是一个个函数

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

谢谢解答!

bud 发表于 2020-10-15 10:48:15

fall_bernana 发表于 2020-10-14 10:24
funIn() 返回的是方法的return返回值
funIn返回的方法对象

谢谢解答!
页: [1]
查看完整版本: python闭包返回值为函数名称和函数名称加括号的时候有什么区别