Python的名字绑定
当前位置:以往代写 > Python教程 >Python的名字绑定
2019-06-14

Python的名字绑定

Python的名字绑定

Python的名字绑定

在Python中,工具是通过名字举办关联和引用的。Python通过名字绑定操纵来引入名字。

Python中的所谓的代码块就是一段作为执行单位的措施。好比:模块、函数、类界说。在交互式情况中输入的呼吁也是代码块的一种。一个Python剧本文件也是一个代码块。尚有就是,当我们在呼吁行上利用-c选项指定的呼吁也是一个代码块。通报给内建函数eval()和exec()的字符串参数也是代码块的一种。

代码块是以执行帧的方法被执行的,一个执行帧包括了一些打点信息,可以用于调试。执行帧还会在执行完当前的代码块今后指定在那里,以奈何的方法执行接下来的代码。

Python中的浸染域界说了名字在代码块中的可见性。假如在代码块中界说了一个局部变量,那么这个局部变量的浸染域就是地址的这个代码块。假如这个界说产生在函数体内,则这个变量的浸染域就扩展到包括在这个函数中的任何代码块中,可是,假如包括在这个函数中的一个代码块中,同样的名字被绑定到了差异的工具上,那么外面的名字将不能被扩展到这个代码块中。

def out_func():
    #a的浸染域在out_func这个函数中
    a = 0
    b = 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中。
    b = 1

在Python中,界说在类代码块中名字只能在类中可见,而且类中的名字的浸染域不能扩展到类中的要领中。假如在类界说中呈现了生成器表达式和列表展开,那么类中的名字也不能扩展到这些表达式中,因为列表展开和生成器表达式的实现都是利用函数浸染域的。

class C:
    a = 0
    # 在列表表达式中,a会因为未界说而抛出NameError异常
    b = list(a + i for i 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 异常。

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

#p#分页标题#e#

在Python中,代码块中的局部变量可以通过扫描整个代码块来得到绑定的名字,所以在上面的代码中,a这个名字在执行print的时候通过对代码块的扫描已经被找到,可是名字a的绑定操纵却还没有产生,所以呈现了错误。

在上面的代码中,假如我们需要外面界说的全局变量a,则可以利用global 语句举办声明。

>>> a = 10
>>> def function():
global a
print(a)
a = 20#这里并不引入新的名字,而是将全局变量a绑定到20上
>>> function()
10
>>> a
20

global 语句的浸染是,使得后头对通过这条语句声明的工具的引用,利用的是顶层名字空间中的名字。在顶层名字空间中,包括了全局名字空间和内建名字空间,全局名字空间会首先被搜索,假如没有找到,会对内建名字空间举办搜索。global 语句必需呈此刻名字利用之前。

假如在外围浸染域中的自由变量包括了一个global声明,则这个自由变量被认为是全局的。

内建名字空间

在查找内建名字空间的时候,会会见当前代码块的全局名字空间中的 __builtins__名字,这个名字引用的是一个名字字典可能是一个模块。在 __main__ 模块中, __builtins__ 的引用是内建模块 builtins,然而,假如是在其他模块中, __builtins__ 引用的是 builtins 模块的名字字典。

留意:

CPython的实现中,不妙手动修改 __builtins__ 这个变量,假如需要包围这个内建名字空间中的名字,需要导入 builtins 模块,然后修改这个模块中相应的属性。

    关键字:

在线提交作业