十九、Python的函数-作用域

一、Python作用域基础

作用域针对的是变量。在使用同一个变量名时,会出现作用域问题。如右边的x,在函数里与函数外是不同的变量。

• 一个def内定义的变量名能够被def内部使用。不能在函数外部引用这个变量名。

• def内的变量名与def外的变量名并不冲突。在def内赋值的与def外赋值的相同变量名是不同的变量。

变量名有如下三种不同作用域:

1、全局:在def外定义的变量名是全局变量

2、本地:在def内部定义的叫做本地变量

3、其它:嵌套def时,各自的变量也是独立的。

二、作用域法则

内嵌的模块是全局作用域,全局作用域的作用范围仅限于单个文件,每次的函数的调用都创建了一个新的本地作用域,赋值的变量名除非声明全局变量或非本地变量(Python3.x有非本地变量说法),否则均为本地变量。所有其它的变量名都可以归纳为本地、全局或者内置。

变量名使用时,查找顺序:LEGB

L:本地变量名 - 在本地是否使用此变量名赋值过。

E:上一层结构中def或lambda的本地变量名 - 上一层是否使用此变量名赋值过。

G:全局变量名 - 在整个文件里是否对变量名赋值过。

B:内置变量名 - Python内部是否存在此变量名。

要是都找不到相应变量名,就会报错。

三、global语句

在函数内,想改变全局变量,可以使用global语句来定义此变量为全局变量,如下所示。

在myfunc函数里,都重新赋值了g与l,但在函数执行后,只有g改变了。当使用global g 之后,当前函数里所使用的所有对变量g的更改都会对全局变量g进行更改。

除了这个方法,还有引用自己的方法(交互模式里,可以import main)与sys.modules的方法(可以使用引用过的所有模块,交互模式里本身可以用main方式),具体如下。

四、作用域与嵌套函数

被嵌套函数的作用域也是上级函数里:

在这里,想调用inner函数,必须是在函数outer里面,不能直接使用。这个时候,我们可以返回内部函数的方法来提取内部函数:

工厂函数

工厂函数为:根据要求的对象,一个能够记住嵌套作用域的变量值的函数。这种功能,使用类可以更好的实现,但使用函数也能简单实现。

可以使用lambda,把之前函数变为:

关于lamdba的使用可以参考:https://www.cnblogs.com/evening/archive/2012/03/29/2423554.html

循环变量

执行后,返回值可能不是我们想象的结果:

原因在于,i x的时候,i的值取的是for循环结束后的最后一个(4)。我们需要写成lambda x, i=i: i x,这样,lambda里的i是本地变量,跟for循环里的i不冲突,优化后如下:

五、nonlocal语句

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190211B0J31W00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券