首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

唠唠python的作用域,看看每个变量都为自己打下了多少江山

前言

不管是学习 C/C++,java,在学习函数(方法)或者变量,都会学习到一个关于变量的知识--作用域,这基本是在所有编程语言中都会涉及到的概念.这关乎到你代码中变量的作用范围,在计算机世界中是必须要遵守一定的规则的,毕竟计算机是科技的产物,咱们是这是新时代,不兴旧时代地主劣绅强占豪夺那套,哈哈~~.回归正题,说到变量的作用域,那不得不了解关于函数的概念因为我们常见的变量作用域,一般是关于一个变量在函数内外的使用范围,其实我们对函数并不陌生,在初高中的时候我们在数学中就学过相关概念,表达式 f(x)=y,是不是跟我们编程中的函数是很类似的,数学中描述是:'凡此变数中含彼变数者,则此为彼之函数'.大白话的意思就是函数指的是一个变量随着另一个变量的变化而变化,其中的核心是两个量的对应法则.使用函数的好处:不仅可以减少冗余和提升代码可重用性,还可以对流程进行分解,使用分治的思想让复杂问题得以简单解决

数学中的函数表达:

f(x)=y

Python 中的函数定义:

代码语言:javascript
复制
def functioName(x1,x2.....xn):  #f(x)
	
	<语句块>
  ......
  return value  #y

既然每个编程语言都有涉及到变量的作用域,在 Python 和其他编程语言中有什么不同呢?

什么是作用域

我们都知道,函数是将一些语句集合到一起,可重复使用的程序片段,在这些片段中定义的变量必不可少的是变量的归属,像西周的分封制,每个诸侯只能管理自己的封邑,且服从大 boss 周天子的命令.在古装剧中可能大家都看过大王都喜欢跟自己妃子吹:看,这是孤为你打下的江山~普天之下,莫非王土,率土之滨,莫非王臣,周天子总揽全局类似全局变量

在 Python 中一个变量的作用域,也就是可使用变量的地方,是由赋值的位置决定的.因为在赋值后 Python 的变量会在此处创建,而对于函数内的语句是一种可重复使用的程序片段,在函数内和函数外定义的变量有什么联系呢?在 Python 中变量的作用域一般可归纳为三种:本地变量,全局变量,内置变量,下面用简单的实例来说明:

代码语言:javascript
复制
a = 50

def f_sum():
  b = a + 20
  print(b)
 
f_sum() #调用函数

我们先来看执行结果:

从结果上可以看出.函数中的加法计算,使用的是函数外的 a 变量.对于 f_sum()这个函数来说.a 是他的上一级定义的变量,而 b 是本地变量.进一步分析,通过变量名赋值创建或者改变本地变量.在上述代码中,函数域中的变量 b 创建时使用了上一级的 a 变量,这在 Python 中是允许的,我通常称之为就近原则,就是当函数中使用的变量在函数内找不到,就会往上一级寻找同名变量,直到找到为止,这在 java 中是不允许,这也是 Python 的独特之处.

这里我使用 PHP 来对比一下

代码语言:javascript
复制
<?php
$x = 23;

function hello(){
	echo $x;
}

hello();
?>

执行结果如下,提示变量 x 没有被定义过.

同时函数中也可以定义同上级同名的变量,通过下面的例子来看看有何微妙之处:

代码语言:javascript
复制
a = 50


def f_sum():
    a = 15
    b = a + 20
    print(b)

f_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 为自己保留的特殊名称

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/e0b8c16e3b62e4951979235ea
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com