Python中看似没用的写法,却是老手都不一定会的
创始人
2025-07-08 10:31:27
0

一次无意间看到如下的代码:

心想:咦?这不是脱裤子放屁吗?函数里面直接使用变量就好了,非要定义成函数参数。

结果没想到这是解决问题的关键。今天我们研究一下这玩意到底解决什么问题以及它的原理。

现在我们从最简单的函数使用外部变量的情况开始:

为了在函数中使用外部的变量,这是最直观的做法。这种在函数中直接使用外部定义的变量,还有一种叫法:'闭包'。

我相信就算不了解 python 查找变量规则的初学者,也能一下子理解函数执行后会输出什么。因为 python 就是为了让其符合直觉才把规则设计成这样。

现在稍微修改一下代码:

在函数执行之前,修改了外部的变量,大家认为函数执行后打印了什么?

看看结果:

不知道你猜对了没有,不过我是觉得这个结果同样符合直觉。

你也觉得结果符合直觉吗?

这是因为函数里面使用外部变量,就是要表达:“执行 print 时,获取变量此时此刻的值。

那么,现实中会不会出现一些场景,我们就是希望函数执行时,得到的是 创建函数的时候,外部变量的值,而非执行时刻的值 ?

没错,就是文章开篇的写法:

真的存在这样子的场景吗?而且,这是什么原理?

我们可以归纳以上代码的特点:

  • 定义了函数
  • 函数内部,希望使用外部定义的变量
  • 定义函数后,并没有立刻执行,并且当函数执行的时候,使用的外部变量很可能已经被修改了

由于 python 写交互的程序不多,一个函数的执行时机基本上都是我们使用代码明确编写。但是大概有2种例外情况:

  • 把函数交给别的调度器,在合适时机执行。比如多线程多进程
  • 在界面编程中,绑定各种事件。事件函数只会在用户与界面交互时才被触发执行

在这些场景中,最容易出现的情况是,在一个循环遍历中,定义函数,绑定函数。下面是一个循环创建10个按钮,点击时界面出现提示信息:

上面的代码创建了10个不同的函数对象,可惜的是,行7的变量 idx 是外部的变量 idx(行4),并且在循环执行过程中,idx 的值不断增加,最终的值停留在 9。

因此,界面上不管点击哪个按钮,显示信息都是 9

现在,我们使用之前学会的套路,定义函数参数默认值解决:

我特意让参数名与外部变量不一致,这更容易理解原理。

到底为什么这样子写可以解决问题,我们不妨把循环给展开(只展开2次):

注意行15 与 行23 ,定义函数的时候,我们把此刻的 idx 值,付给了参数 num 作为默认值。相当于如下代码:

此时,这个默认值不再随 idx 修改而改变。所以每个按钮绑定的函数,看似代码逻辑是一模一样,但是每个函数的参数 num 都是不一样的值。

你学会了吗?

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
P2P的自白|我不生产内容,我... 现在一提起P2P,人们就会联想到正在被有关部门“围剿”的互联网理财服务。×租宝事件使得劳...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...