前言
不管是学习C/C++,java,在学习函数(方法)或者变量,都会学习到一个关于变量的知识--作用域,这基本是在所有编程语言中都会涉及到的概念.这关乎到你代码中变量的作用范围,在计算机世界中是必须要遵守一定的规则的,毕竟计算机是科技的产物,咱们是这是新时代,不兴旧时代地主劣绅强占豪夺那套,哈哈~~.回归正题,说到变量的作用域,那不得不了解关于函数的概念因为我们常见的变量作用域,一般是关于一个变量在函数内外的使用范围,其实我们对函数并不陌生,在初高中的时候我们在数学中就学过相关概念,表达式f(x)=y,是不是跟我们编程中的函数是很类似的,数学中描述是:'凡此变数中含彼变数者,则此为彼之函数'.大白话的意思就是函数指的是一个变量随着另一个变量的变化而变化,其中的核心是两个量的对应法则.使用函数的好处:不仅可以减少冗余和提升代码可重用性,还可以对流程进行分解,使用分治的思想让复杂问题得以简单解决
数学中的函数表达:
f(x)=y
Python中的函数定义:
def functioName(x1,x2.....xn): #f(x) <语句块> ...... return value #y既然每个编程语言都有涉及到变量的作用域,在Python和其他编程语言中有什么不同呢?
什么是作用域
我们都知道,函数是将一些语句集合到一起,可重复使用的程序片段,在这些片段中定义的变量必不可少的是变量的归属,像西周的分封制,每个诸侯只能管理自己的封邑,且服从大boss周天子的命令.在古装剧中可能大家都看过大王都喜欢跟自己妃子吹:看,这是孤为你打下的江山~普天之下,莫非王土,率土之滨,莫非王臣,周天子总揽全局类似全局变量
在Python中一个变量的作用域,也就是可使用变量的地方,是由赋值的位置决定的.因为在赋值后Python的变量会在此处创建,而对于函数内的语句是一种可重复使用的程序片段,在函数内和函数外定义的变量有什么联系呢?在Python中变量的作用域一般可归纳为三种:本地变量,全局变量,内置变量,下面用简单的实例来说明:
a = 50def fun_sum(): b = a + 20 print(b) fun_sum() #调用函数我们先来看执行结果:
从结果上可以看出.函数中的加法计算,使用的是函数外的a变量.对于f_sum()这个函数来说.a是他的上一级定义的变量,而b是本地变量.进一步分析,通过变量名赋值创建或者改变本地变量.在上述代码中,函数域中的变量b创建时使用了上一级的a变量,这在Python中是允许的,我通常称之为就近原则,就是当函数中使用的变量在函数内找不到,就会往上一级寻找同名变量,直到找到为止,这在java中是不允许,这也是Python的独特之处.
这里我使用PHP来对比一下
<?php$x = 23;function hello(){ echo $x;}hello();?>执行结果如下,提示变量x没有被定义过.
同时函数中也可以定义同上级同名的变量,通过下面的例子来看看有何不同之处:
a = 50def fun_sum(): a = 15 b = a + 20 print(b)fun_sum() # 调用函数print(a)执行结果如下:
同样适合就近原则,函数内定义了同名变量就使用函数内定义的,但是函数内定义的变量只能在函数内部起作用,在函数执行完毕之后,函数内部的变量值对外部是无效的,全局变量并不受到影响,所以外部输出的依然是全局变量a的值,就像西周各个诸侯,只在自己的封地拥有管理权.其实Python的变量作用跟javascript的作用域类似
总结
像上述Python这种使用未识别变量名的方式,是一种叫做LEGB的机制.该机制非常简单,所谓的LEGB机制是指:当遇到未认证的变量名时,Python依次搜索本地作用域L,上层结构中的本地作用域E,全局作用域G,内置作用域B,这个过程如下图所示:
Python 在查找"变量"时,是按照 LEGB 规则查找的:Local–>Enclosed–>Global–>Built in
Local 指的就是函数或者类的方法内部
Enclosed 指的是嵌套函数(一个函数包裹另一个函数,闭包)
Global 指的是模块中的全局变量
Built in 指的是 Python 为自己保留的特殊名称