Python函数中的作用域规则详解

作者:一只懐坏旭 时间:2023-02-14 04:32:28 

Python是静态作用域语言,但是它自身是一个动态语言。在Python中变量的作用域是由变量在代码中的位置决定的,与C语言有些相似,但不是完全一样。

在Python 2.0及之前的版本中,Python只支持3种作用域,即局部作用域,全局作用域,内置作用域;在Python
2.2中,Python正式引入了一种新的作用域 — 嵌套作用域;嵌套作用域的引入,本质上为Python实现了对闭包的支持。

1、简单介绍一下闭包

def test():
 A = 3
 B = 4
 def stu():
 C = 3
 return A+B+C
 return stu
stu = test()
stu

在上述此代码中stu方法定义在test的内部,内部函数stu即可以使用外部函数test的变量,我们称这种行为叫做闭包。

2、在Python中,并不是任何代码块都能引入新的作用域

Python中不是任何代码块都可以引入新的作用域这与C有很大的不同:

在C中:

#include<stdio.h>
int main() {    
if(2 > 0) {        
int i = 0;
   }
   printf("i = %d", i);    
   return 0;
}

在上述代码中,if子句引入了一个局部作用域,变量i就存在于这个局部作用域中,但对外不可见,因此,接下来在printf函数中对变量i的引用会引发编译错误。

但是,在Python中却并非如此:

if True:
   i = 0
print i

在上述代码中,if子句并没有引入一个局部作用域,变量i仍然处在全局作用域中,因此,变量i对于接下来的print语句是可见的。

实际上,在Python中,只有模块,类以及函数才会引入新的作用域,其它的代码块是不会引入新的作用域的。

在Python中,使用一个变量之前不必预先声明它,但是在真正使用它之前,它必须已经绑定到某个对象;而名字绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量,不论这个名字绑定发生在当前作用域中的哪个位置。

>>> f()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 2, in f
NameError: name 'i' is not defined
>>>

运行结果报错

NameError: name &lsquo;i&rsquo; is not defined

程序运行时,Python首先在函数f的本地作用域中查找变量i,查找失败,接着在全局作用域和内置作用域中查找变量i,仍然失败,最终抛出NameError异常。

>>> def f():
...     i = 8
...     print(i)
...
>>> f()
8
>>> print(i)
0
>>>

运行结果显示

8和0

i = 8是一个名字绑定操作,它在函数f的局部作用域中引入了新的变量i,屏蔽了全局变量i,因此f内部的print语句看到的是局部变量i,f外部的print语句看到的是全局变量i。

>>> i = 0
>>> def f():
...     print(i)
...     i = 0
...
>>> f()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 2, in f
UnboundLocalError: local variable 'i' referenced before assignment
>>>

运行结果报错

UnboundLocalError: local variable &lsquo;i&rsquo; referenced before assignment

在上述中,函数f中的变量i是局部变量,但是在print语句使用它的时候,它还未被绑定到任何对象之上,所以抛出异常。

3、在Python中,名字绑定在所属作用域中引入新的变量,同时绑定到一个对象。

名字绑定发生在以下几种情况之下:

  • 参数声明:参数声明在函数的局部作用域中引入新的变量;

  • 赋值操作:对一个变量进行初次赋值会在当前作用域中引入新的变量,后续赋值操作则会重新绑定该变量;

  • 类和函数定义:类和函数定义将类名和函数名作为变量引入当前作用域,类体和函数体将形成另外一个作用域;

  • import语句:import语句在当前作用域中引入新的变量,一般是在全局作用域;

  • for语句:for语句在当前作用域中引入新的变量(循环变量);

  • except语句:except语句在当前作用域中引入新的变量(异常对象);

来源:https://blog.csdn.net/qq_45691220/article/details/123354446

标签:Python,作用域,规则
0
投稿

猜你喜欢

  • 网易2016研发工程师编程题 奖学金(python)

    2021-11-21 19:37:54
  • 人生苦短我用python python如何快速入门?

    2021-06-01 03:57:09
  • pycharm无法安装第三方库的问题及解决方法以scrapy为例(图解)

    2022-11-01 20:53:28
  • Python语言的12个基础知识点小结

    2023-08-23 10:12:07
  • Python实现将n个点均匀地分布在球面上的方法

    2021-02-21 20:56:33
  • 详解JavaScript的垃圾回收机制

    2024-06-23 18:05:52
  • Django的CVB实例详解

    2023-11-04 06:47:26
  • Python中装饰器兼容加括号和不加括号的写法详解

    2022-08-09 10:46:25
  • Python爬虫requests库多种用法实例

    2021-01-10 13:31:56
  • 如何基于python对接钉钉并获取access_token

    2023-11-27 04:25:07
  • Python实现RSA加密解密

    2022-04-22 19:07:41
  • PHP获取url的函数代码

    2023-10-15 12:45:00
  • JS异步宏队列与微队列原理区别详解

    2024-04-22 13:26:36
  • 利用机器学习预测房价

    2023-08-10 21:25:50
  • 屏蔽Flash 右键菜单的方法

    2008-05-24 07:21:00
  • webp 格式图片显示异常分析及解决方案

    2023-08-26 22:33:27
  • 一个较复杂的字符串截取函数

    2009-11-02 10:45:00
  • Python 实现敏感目录扫描的示例代码

    2021-08-21 05:47:14
  • mysql 列转行的技巧(分享)

    2024-01-18 09:54:13
  • 学习ASP.NET八天入门:第六天

    2007-08-07 13:48:00
  • asp之家 网络编程 m.aspxhome.com