鱼C论坛

 找回密码
 立即注册
查看: 2066|回复: 7

[已解决]函数闭包,参数传递的问题

[复制链接]
发表于 2020-7-10 18:36:47 | 显示全部楼层 |阅读模式

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

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

x
今天看一个网站,发现下面的代码有点看不懂


#闭包函数,其中 exponent 称为自由变量
def nth_power(exponent):
    def exponent_of(base):
        return base ** exponent
    return exponent_of # 返回值是 exponent_of 函数
square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方

print(square(2))  # 计算 2 的平方
print(cube(2)) # 计算 2 的立方


运行结果为:
4
8


我想知道上面只给  exponent  变量赋值了,base 变量根本没有赋过值,为什么还能算出结果来呢?

另外,新手求教学资料推荐,关于python的,那种非常好的书籍,有没有哪位推荐一下啊?最好是能免费看的。
最佳答案
2020-7-10 18:55:11
guozhenyu411 发表于 2020-7-10 18:51
还是没太明白,我把代码改了一下 ,把  base  换成了  exponent ,算出来就变成
4
4





你理解下下面这个,我这里的函数名更简单,你的函数名看的比较累,可能会不方便你的理解

原理是一模一样的,小甲鱼的闭包课后作业的:


要知道 当函数名带上括号时候,函数返回的是函数运行的结果

当函数名不带括号时候,函数返回的是一个函数体

def funX(x):
    def funY(y):
        return x*y
    return funY


因为你定义的 funX 函数返回的是 funY ,当函数不带括号时候就代表一个函数体,也就是这 funY 一整个函数

所以你这里 temp= funX(8) ,带上括号,所以是把 x = 8 传入后调用函数运行的结果,就可以看成:
def funX(8):
    def funY(y):
        return 8*y
    return funY

又因为返回的是 funY 不带括号,是整个函数体,所以实际上 temp= funX(8)  就等于了 temp = funY 即代码可以看成这样:
def funY(y):
    return 8*y

此时你在对 temp(5) 那么就是 将 funY 的 y 参数赋值为 5

所以最后返回的结果是 return 8 * 5

第一次是对 x 传入参数,因为第一次调用返回的是个函数,则第二次传入的参数就是返回后函数的参数值了,即第一次 x = 8,第二次 y = 5



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

使用道具 举报

发表于 2020-7-10 18:39:08 | 显示全部楼层
square是一个函数对象,也就是exponent_of,
在print(square(2))的时候,就给base传参了,你可以理解为是print(exponent(2))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-10 18:48:06 | 显示全部楼层


def nth_power(exponent):
    def exponent_of(base):
        return base ** exponent
    return exponent_of  # 返回值是 exponent_of 函数


这里注释画重点,当你 square = nth_power(2) ,将参数 exponent_of = 2 ,然后我们先计算函数 nth_power(2)

而 nth_power(2) 返回值的是 exponent_of(base) 函数,则此时 square 即为  exponent_of 函数 ,没带括号

当你 square(2) 时候 等价于  exponent_of(2) ,即 base = 2 ,所以返回值为 base ** exponent =  2**2

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

使用道具 举报

 楼主| 发表于 2020-7-10 18:51:00 | 显示全部楼层
还是没太明白,我把代码改了一下 ,把  base  换成了  exponent ,算出来就变成
4
4



#闭包函数,其中 exponent 称为自由变量
def nth_power(exponent):
    def exponent_of(exponent):
        return exponent ** exponent
    return exponent_of # 返回值是 exponent_of 函数
square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方

print(square(2))  # 计算 2 的平方
print(cube(2)) # 计算 2 的立方
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-10 18:55:11 | 显示全部楼层    本楼为最佳答案   
guozhenyu411 发表于 2020-7-10 18:51
还是没太明白,我把代码改了一下 ,把  base  换成了  exponent ,算出来就变成
4
4





你理解下下面这个,我这里的函数名更简单,你的函数名看的比较累,可能会不方便你的理解

原理是一模一样的,小甲鱼的闭包课后作业的:


要知道 当函数名带上括号时候,函数返回的是函数运行的结果

当函数名不带括号时候,函数返回的是一个函数体

def funX(x):
    def funY(y):
        return x*y
    return funY


因为你定义的 funX 函数返回的是 funY ,当函数不带括号时候就代表一个函数体,也就是这 funY 一整个函数

所以你这里 temp= funX(8) ,带上括号,所以是把 x = 8 传入后调用函数运行的结果,就可以看成:
def funX(8):
    def funY(y):
        return 8*y
    return funY

又因为返回的是 funY 不带括号,是整个函数体,所以实际上 temp= funX(8)  就等于了 temp = funY 即代码可以看成这样:
def funY(y):
    return 8*y

此时你在对 temp(5) 那么就是 将 funY 的 y 参数赋值为 5

所以最后返回的结果是 return 8 * 5

第一次是对 x 传入参数,因为第一次调用返回的是个函数,则第二次传入的参数就是返回后函数的参数值了,即第一次 x = 8,第二次 y = 5



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

使用道具 举报

 楼主| 发表于 2020-7-10 19:09:21 | 显示全部楼层
知道了,多谢!还是你这个看的清楚啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-10 20:05:10 | 显示全部楼层
这个函数还可以写成:
nth_power = lambda x, /: x.__pow__
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-10 20:28:47 | 显示全部楼层
什么意思?

nth_power = lambda x,y: x**y

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-11 12:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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