VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Python的名字绑定

Python的名字绑定

在Python中,对象是通过名字进行关联和引用的。Python通过名字绑定操作来引入名字。

Python中的所谓的代码块就是一段作为执行单元的程序。比如:模块、函数、类定义。在交互式环境中输入的命令也是代码块的一种。一个Python脚本文件也是一个代码块。还有就是,当我们在命令行上使用-c选项指定的命令也是一个代码块。传递给内建函数eval()和exec()的字符串参数也是代码块的一种。

代码块是以执行帧的方式被执行的,一个执行帧包含了一些管理信息,可以用于调试。执行帧还会在执行完当前的代码块以后指定在何处,以怎样的方式执行接下来的代码。

Python中的作用域定义了名字在代码块中的可见性。如果在代码块中定义了一个局部变量,那么这个局部变量的作用域就是所在的这个代码块。如果这个定义发生在函数体内,则这个变量的作用域就扩展到包含在这个函数中的任何代码块中,但是,如果包含在这个函数中的一个代码块中,同样的名字被绑定到了不同的对象上,那么外面的名字将不能被扩展到这个代码块中。

1
2
3
4
5
6
7
8
9
def out_func():
    #a的作用域在out_func这个函数中
    = 0
    = 0
    def in_func():
    #a的作用域从out_func扩展到了in_func中,因为in_func这个代码块包含在out_func中
    print(a)
    #out_func函数中的b不能扩展到in_func中,因为在in_func中,b重新绑定到了不同的对象上,所以在out_func中的b的作用域不能扩展到in_func中。
    = 1

在Python中,定义在类代码块中名字只能在类中可见,并且类中的名字的作用域不能扩展到类中的方法中。如果在类定义中出现了生成器表达式和列表展开,那么类中的名字也不能扩展到这些表达式中,因为列表展开和生成器表达式的实现都是使用函数作用域的。

1
2
3
4
5
6
7
class C:
    = 0
    # 在列表表达式中,a会因为未定义而抛出NameError异常
    = list(a + for in range(10))
    def method(self):
        #由于定义在类中的名字不能扩展到方法中,所以下面的语句是错误的,会抛出a未定义的NameError异常
        print(a)

当在一个代码块中使用一个名字的时候,会对最近的外围作用域进行解析,以查找这个名字。所有的这些在当前代码块中可见的作用域的集合,称为

当前的代码块的环境。

名字绑定和作用域的关系

如果一个名字绑定到一个代码块中,除非这个名字声明为nonlocal(nonlocal声明的作用是:使得变量在外围作用域中,在全局作用域之前被解析),否则这个名字就是这个代码块的局部变量。如果一个名字被绑定到模块级别,则这个名字的作用域是全局的,这个变量是全局变量(模块中的变量,对于模块而言是局部变量,而对于模块中的代码块而言,则是全局变量)。如果一个名字在一个代码块中使用,但是不是在这个代码块中被定义的,则这个变量就是一个自由变量。

名字绑定相关的异常

如果在进行名字查找的时候,名字没有被找到,则会抛出一个 NameError 异常,如果名字引用的是一个局部变量,但是这个名字还没有被绑定到这个局部变量,则会抛出一个 UnboundLocalError 异常(UnboundLocalError 是 NameError的子类)。

发生名字绑定行为的情况

发生名字绑定的行为主要有:

通常的给函数传递参数的时候,参数名会和传递过来的对象进行绑定

使用import语句进行导入的时候,其中 from ... import * 语句会将被导入的模块中的所有可以被导入的名字进行绑定操作

类定义的时候

函数定义的时候

进行赋值操作的时候

在for循环的for语句中

在with语句中的as后面

在expect语句中的as后面

Python中的名字绑定的Pitfall

在Python中,名字绑定的一些规则,会导致在使用名字的时候,出现不能理解的错误,特别是对于有C、C++ 和 Java经验的用户。

在Python中,名字绑定操作无论发生在当前块的 任何 位置,在这个代码块中对这个名字的引用都会使用在当前块中绑定的对象。那么,问题就来了,如果我们在名字绑定操作发生之前对这个名字进行了引用,那么就会出现错误,抛出 UnboundLocalError 异常。

1
2
3
4
5
6
7
8
9
10
11
>>> a = 10
>>> def function():
print(a)
= 20# a的绑定操作发生在print之前
>>> function()
Traceback (most recent call last):
  File "<pyshell#5>", line 1in <module>
    function()
  File "<pyshell#4>", line 2in function
    print(a)
UnboundLocalError: local variable 'a' referenced before assignment

相关教程