【老板叫我了】轻松理解python变量的作用域 和 闭包

微信扫一扫,分享到朋友圈

【老板叫我了】轻松理解python变量的作用域 和 闭包

技术不需要枯燥的术语也可以被理解

别人的每次提问都能提醒自己学习的东西是什么

所以我写了这个系列

希望大家能在轻松愉快的提问中理解枯燥的技术点

某天,小方正在工位上哼哧哼哧写代码,突然微信里老板又叫他

小方啊,你过来一下

我心里一紧,是我上个月请假次数太多了被注意了吗?还是我偷偷摸鱼被举报了?怀着忐忑不安的心,我来到了老板的办公室

哎,小方你来啦!上次不是问你选python还是选java嘛 ,我想了想就做个数据分析,还是简单点用python吧。看了一遍python的基础语法,怎么发现这跟我当年学的完全不一样啊!函数内部怎么能访问外部的成员变量呢?你快给我讲讲

(原来是问这个啊)噢,老板,这个说的是python变量的作用域….

啥的作用域?

变量!变量的作用域!! 我们每个人都在接触变量这个概念。 但变量是什么东西呢? 说白了他就是计算机里的一块内存空间,就是存放数值的地方。我们修改变量的值实际上修改的是内存空间存储的值。当我们写 a = 1 这行代码时,实际上是干了 两件事:

一是新建了一块内存空间存放 a

二是把 1 这个值塞到这个内存空间里

我们可以在代码的许多地方定义变量,其实就是新建了许多个存放数值的内存空间

噢噢,这些我上大学的时候学过,那你刚说的python的作用域是怎么回事?

「作用域」简单理解就是变量起作用的区域。我们定义一个变量后肯定不是到处都能使用的,这就需要我们明白 变量的作用范围 ,也就是作用域。其实很简单,就是一个洋葱结构,一环套一环。

变量的作用域遵循一个原则, 里面的可以访问外面的,外面的不能访问里面的 。老板你完全不需要记这些名词啦,规则啦,一个例子你就懂了:

看,很简单吧

噢,原来我直接定义的变量就是全局变量啊,不就是相当于java里加了static修饰的变量嘛,怪不得能直接访问,早说嘛

对对对,老板你最聪明了!你是最棒的!

那个嵌套作用域是咋回事啊?我咋从来没见过?

这是python特有的写法。 python可以在 函数内部再定义函数 ,也就实现了函数嵌套。嵌套函数里面的变量就是嵌套的局部变量,外部函数就是局部变量,他们一样遵循变量访问的原则哒

胡说!我刚刚试了一下,嵌套函数不能修改外部函数的变量!你是不是不行啊?!回头就扣你工资!

别别别! 老板!我刚说的是“访问”,访问啊!你用嵌套函数修改外部函数变量,这是闭包啊,闭包当然无法直接修改局部变量了,他只有访问权,没有修改权!我现在给你写个例子,你别扣我工资啊啊!!

那你刚刚一本正经的说什么里面访问外面的,我怀疑你小子在晃点我!

要修改也可以… 使用 nonlocal 关键字声明一下就可以改了

真是的,话都不说清楚。对了,你刚刚说的闭包是啥玩意?

(呜呜呜)我们定义的函数,实际上是一个处理一段逻辑的代码块,我们可以叫它「一块代码」,也可以形象地说这是一个「包」。 「闭包」呢,就是这个「包」它不满足只处理自己包含的这些逻辑,还想引用函数之外的一些变量 ,当它满足这些条件时,就把这个『函数+变量』整体称为 闭包

关于闭包有一道经典面试题,老板你可以看下:

下面代码输出的结果是什么?

这么简单,不就是 [0,2,4] 吗?你当我傻么

是 [4,4,4] 我给你跑一下…

刚才我不是说过变量的本质么。看上去这个 for 循环的索引值 i 每次都作为嵌套函数的一部分添加到 list 里了。但您仔细想想, return x * i 是什么时候被调用的?是 print f(2) 的时候才调用的对吧,这时候的 x * ii 的值是多少呢? i 只是一块被定义出来的内存空间,随着 for 循环一次次改变自己存储的值,当 for 循环结束时,它的值就不会再变了,所以 i 的值在被调用的时候一直是 2,结果也就是 [4 ,4,4] 了。

那我就想要 [0,2,4] 咋办?

额,也有办法。我第一次做这道题的时候也以为是 [0,2,4] ,后面知道正确答案后才发现自己思维过程中有一个盲点。就是我默认每次 for 循环的 i 都存到 func 里了。如果要想要 [0,2,4] ,就是想办法把 i 的值存一下给嵌套函数 func 。而函数的参数本来不就是复制值到函数内部么。于是我就在 func 外面再定义一个函数,参数值是 i ,目的就是把 i 保存下来提供给嵌套函数使用。这样嵌套函数和 i 就组成了一个闭包,结果也符合预期

嗨,我刚没看清。这玩意有啥用啊,花里胡哨的,这帮面试官就会整人!

也不是完全没用…. 闭包的变量可以用来保存上一次的运行环境。当我们有需求是需要上一次的运行结果作为这一次的参数时,就可以用闭包来解决。比如你写一个「下棋游戏中棋子移动」的代码,棋子的每次移动都是用上一次的坐标为起点的。这时候就可以用闭包来解决了。这里也有一道面试题,老板你要不要看看?

我看面试题有啥用?! 等会,那啥,待会发我微信就好了

(老板你果然想…)好的。。

好了好了,这些我都会了,也没什么难的嘛,你先回去吧,好好工作啊,公司还得靠你!

(尴尬)哈哈,那我先走了

(关门)

过了一会,我把题目发给了老板:

答案是:

输出结果:

随手一赞,好运爆棚!

以上就是本期的全部内容啦,如果你喜欢这篇文章的内容,或者哪怕有一点小小的帮助,可以点个赞再走哦 ~

求赞,求关注,求三连 ! 我翻个跟斗谢谢大伙的捧场了!

我叫方木,你们也可以叫我小方 ~

每天我都会分享一篇文章给大家

可能是「网络」,可能是「计算机基础」,也可能是「python」,「数据分析」

我一直觉得, 技术不需要枯燥的术语也可以被理解

所以我想把我理解的东西整理分享给大家

如果你有什么建议或者意见的话 欢迎 提给我

你们的每个 点赞关注 都是我持续输出的动力!

我们都在这个世界中挣扎着

欢迎大家和我一起成长

微信扫一扫,分享到朋友圈

【老板叫我了】轻松理解python变量的作用域 和 闭包

有用的SQL语句大全

上一篇

Continuation在JS中的应用

下一篇

你也可能喜欢

【老板叫我了】轻松理解python变量的作用域 和 闭包

长按储存图像,分享给朋友