鱼C论坛

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

[技术交流] 第20讲习题代码以及分析(一)

[复制链接]
发表于 2014-7-30 22:37:40 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 mumudontcry 于 2014-8-2 02:58 编辑

第一行喂@小甲鱼  ,第二行开始
题目我还是不说了(免责声明:要先好好看小甲鱼的好不啦,全让我说了,人家干什么去,再说把题目弄过来,小甲鱼的10鱼币就赚不了啦)

这次测试题有必要说一说了,因为我觉得这讲的东西很容易出错
2
inside是内部函数,在外部函数外面不能使用
3
代码B中,var是内部函数的局部变量,print(var),说明要使用var,注意,如果内层函数有变量跟外层函数变量一样,那么python会为了保护外层函数变量,自己建立一个名字一样的内层函数的局部变量,因此,这里的var是相当于没有定义的
nonlocal var
4
funOut()
5
funOut()()
为什么第四题和第五题是这样呢?

先说说5,我拿视频里的例子来说明这个问题:
def FunX(x):
    def FunY(y):
        return x*y
    return FunY

令i = FunX(8),那么……程序看不懂,数学的“代入消元”总会吧?把x=8带入FunX(x)中,得到:
def FunX(8):
    def FunY(y):
        return 8*y
    return FunY


所以说,返回值是8*y(你他喵的在逗我?!)……………………么?是,也不是,因为y是局部变量,所以FunX当然不可能返回y,那……到底是什么?

你可以理解为,这个时候FunX(8)它对于8这个自变量来说,是一个因变量,数学上它是一个表达式,在程序里由于还带有一个参数,所以他其实是一个函数,而FunX(8)是这个函数的函数名(把它看成一个整体啊焚蛋!),那么既然你是一个函数,就还需要一个自变量才能求值

那使用函数怎么求值呢?当然是“函数名(自变量)”了,在这里函数名是FunX(8),所以答案就是FunX(8)(5)

如果不能理解的话,请看下面的程序(你们可以动手调试一下)

def FunX(x):
    print("我是木,我是第一层",x)

    def FunY(y):
        print("我是林,我是第二层",y)

        def FunZ(z):
            print("我是森,我是第三层",z)
            return x*y*z
        return FunZ


    return FunY

print(FunX(1)(2)(3))


如图所示
知道了这个,那么第五题你应该就可以理解了,那么第四题呢?

第四题和第五题的差别就是在内层函数的return那里函数名多了一个括号,而一个括号就表示,你是不是有调用这个函数,如果你都没有加括号,那当然不会访问到里面了

如果你有type过上面的函数名,你会发现,他们都是function类型的,除非,你所有的值都给上

另外一个方法就是小甲鱼所说的“曲线救国”:
def funOut():
    def funIn():
        print('宾果!你成功访问到我啦!')
    return funIn
go = funOut()
go()

这里,用“代入消元法”,go()就等于funOut()(),嗯……这个等于多少呢?这个就是访问了内层函数啊或者你直接funOut()()

6
#(白色的字-->)小甲鱼的答案里有解析,不过,我现在也不是很清楚,先留着等我清楚了再补上

关于闭包,我就说三点,大家以后记住就一定没有错!
1、只要你的内部函数的局部变量访问了外部函数的局部变量,那么这个内部函数就是闭包
这种访问包括:print局部变量的值,修改局部变量(这个请看2)
2、如果你要修改“可能成为闭包的内部函数”的局部变量的值,那么请在这个局部变量前面加上nonlocal关键字,否则,python将会在内部函数自动创建一个与外部函数局部变量同名的局部变量,达到保护外部函数局部变量的效果,此时,由于内部函数的那个局部变量没有访问外部函数的局部变量,因此,这时候这个内部函数不是闭包
3、闭包一旦形成,如果不重新定义函数,那么函数就不会被销毁,程序不会初始化,比如:
def funX():
    x = 5
    def funY():
        nonlocal x
        x += 1
        return x
    return funY

a = funX()
print(a())
print(a())
print(a())
print("~~~~~~~~~~")

b = funX()
print(b())
print(b())
print(b())

a =funX()相当于是return funY,表示定义了一个函数a,所以a =funY,而type funY后得到的是function,也就是说funY的值是funY的地址,而funY()表示调用这个函数,于是a()就是调用funY,也就是return x,也就是得到的6,于是每一次的使用a()就相当于只是调用funY,所以才不会x =5。所以才会说改变a,才会重新执行x = 5
当b = funX()的时候,x重新变成5
------------------------------------------------我是消魂的分界线-------------------------------------------------
木木提问时间:
请问下面程序会打印出什么,先自己想,再运行看结果:
def funX():
    x = 5

    def funY():
        nonlocal x
        x += 1
        print("木木萌萌哒")
        return x
    def funZ():
        print("Z")

    funZ()
    return funY
funX()
print("~~~~~~~~~~")

a =funX()
a()
print("~~~~~~~~~~")

funX()()
print("~~~~~~~~~~")

a =funX()()
print("~~~~~~~~~~")

print(a)
print("~~~~~~~~~~")

print(funX()())

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
点击
当没节操甲鱼遇上傲娇笨笨的木木
查看我的淘帖,喜欢就点“订阅”吧






QQ截图20140730221007.png

评分

参与人数 1荣誉 +8 鱼币 +8 贡献 +3 收起 理由
小甲鱼 + 8 + 8 + 3 每期点评必看~

查看全部评分

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2014-7-31 14:57:20 | 显示全部楼层
不错,解释得很到位!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-7-31 15:56:28 | 显示全部楼层
略懂~~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-24 19:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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