美文网首页
python中的作用域与命名空间

python中的作用域与命名空间

作者: merryzhou | 来源:发表于2017-07-11 23:16 被阅读0次

python中的几个命名空间:
1.局部命名空间:包含局部变量
2.全局命名空间: 当前模块的最外层的全局变量
3.内置(built-in)命名空间: 包含了内置的变量/关键字等

这三个命名空间分别有各自的生命周期:
1.局部命名空间:函数的局部命名空间,在函数调用时创建,函数返回或者由未捕获的异常时销毁;类定义的命名空间,在解释器读到类定义创建,类定义结束后销毁
2.全局命名空间:模块的全局命名空间在模块定义被解释器读入时创建,解释器退出时销毁
3.内置命名空间:在Python解释器启动时创建,解释器退出时销毁

python代码中查找一个变量按照LEGB的顺序查找:
1.Local:首先搜索,包含局部名字的最内层(innermost)作用域,如函数/方法/类的内部局部作用域;
2.Enclosing:根据嵌套层次从内到外搜索,包含非局部(nonlocal)非全局(nonglobal)名字的任意封闭函数的作用域。如两个嵌套的函数,内层函数的作用域是局部作用域,外层函数作用域就是内层函数的 Enclosing作用域;
3.Global 倒数第二次被搜索,包含当前模块全局名字的作用域;
4.Built-in 最后被搜索,包含内建名字的最外层作用域。

>>> i=2
>>> def func():
...    print(i)
... 
>>> func()
2

注:程序运行过程中LGB一定存在,E不一定存在

>>> i=2
>>> print(i)
2

这种类型的程序,命令空间的说明如下:
<b>Usually, the local scope references the local names of the (textually) current function. Outside functions, the local scope references the same namespace as the global scope: the module's namespace. Class definitions place yet another namespace in the local scope.</b>

还有一个地方需要注意的是;

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

如果内部函数有引用外部函数的同名变量或者全局变量,并且对这个变量有修改.那么python会认为它是一个局部变量,所以在print(i)时该变量还没有定义,出现UnboundLocalError。
那么如果需要修改global中的变量怎么办呢?可以使用global关键字:

>>> i=2
>>> def func():
...   global i
...   print(i)
...   i=3
... 
>>> func()
2
>>> print(i)
3

在python3.X版本中引入了关键字nonlocal,用来在函数或其他作用域中使用外层(非全局)变量
(The nonlocal
statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope。)

i=2
def func():
    i=3
    def func1():
        i=4
        nonlocal i
        print(i)
        i+=1
    return func1
a=func()
a()
print(i)
a()

---outputs---
4
2
4
/usercode/file3.py:7: SyntaxWarning: name 'i' is assigned to before nonlocal declaration
  nonlocal i
#!/usr/bin/python
i=2
def func():
    i=3
    def func1():
        nonlocal i
        print(i)
        i+=1
    return func1
a=func()
a()
print(i)
a()

---outputs---
3
2
4

python中内置了locals和globals2个方法可以查询局部和全局的命名空间

#!/usr/bin/python
i=2
def func():
    j=4
    print("locals:",locals())
print("globals:",globals())
func()

---outputs---
globals: {'__loader__': <_frozen_importlib.SourceFileLoader object at 0x7fb1ce70f0b8>, 
'__spec__': None, '__name__': '__main__', '__cached__': None,
'__builtins__': <module 'builtins' (built-in)>, 
'func': <function func at 0x7fb1ce737b70>, 'i': 2, '__file__': '/usercode/file3.py', '__package__': None, '__doc__': None}
locals: {'j': 4}

locals和globals有个重要的区别:

#!/usr/bin/python
def func1(i, info):
    x = 12345
    print(locals())
    locals()["x"]= 6789
    print("x=",x)
 
y=54321
func1(1 , "first")
globals()["y"]= 9876
print( "y=",y)

---outputs---
{'x': 12345, 'i': 1, 'info': 'first'}
x= 12345
y= 9876

这是因为(待研究为什么这么设计):
1.locals 实际上没有返回局部名字空间,它返回的是一个拷贝。所以对它进行改变对局部名字空间中的变量值并无影响。
2.globals 返回实际的全局名字空间,而不是一个拷贝。所以对 globals 所返回的 dictionary 的任何的改动都会直接影响到全局变量

此外,我们import时有2种方式:
1.from module import xxx
2.import module
在使用第一种时,会把被导入的module种方法和属性放到当前的命名空间中,所以可以直接使用方法和属性进行访问;而在第二种中,模块被导入,保留了自身的命名空间,所以访问其中的方法需要使用module.method()

参考:

  1. Python进阶_关于命名空间与作用域(详解)
  2. Python命名空间和作用域窥探
  3. Python Scopes and Namespaces
  4. 命名空间的本质

相关文章

  • python-命名空间、作用域,和局部函数

    命名空间 Python中变量的使用有作用域的问题,即命名空间(namespace)。任何在函数中 赋值...

  • Python进阶 - 命名空间与作用域

    Python进阶 - 命名空间与作用域 写在前面 如非特别说明,下文均基于Python3 命名空间与作用于跟名字的...

  • python中的作用域与命名空间

    python中的几个命名空间:1.局部命名空间:包含局部变量2.全局命名空间: 当前模块的最外层的全局变量3.内置...

  • 【第10天】python全栈从入门到放弃

    1.动态参数 *位置参数 **关键字参数 2.命名空间和作用域 2.1 命名空间 内置命名空间: python解释...

  • python:命名空间与作用域

    变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称们(键)和它们各自相应的对象们(值)的字典。一个P...

  • 1.Python语言基础

    Python的名称空间与作用域 名称空间名称空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通...

  • 15.Python之名称空间与作用域

    Python之名称空间与作用域 名称空间名称空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通...

  • Python 中命名空间与作用域介绍

    导语:对命名空间和作用域认识很模糊?为了让大家有清晰的认识,本文详细介绍了命名空间类型及作用域,希望能让你对Pyt...

  • 变量作用域

    0. 命名空间 变量作用域1. 变量作用范围:可操作范围2. Python 是静态作用域,变量的作用域源于它在代码...

  • Python中的LEGB规则

    前言 理解LEGB前,首先需要对Python的作用域、命名空间有一定的了解,话题才能继续展开。 命名空间 命名空间...

网友评论

      本文标题:python中的作用域与命名空间

      本文链接:https://www.haomeiwen.com/subject/ebqvhxtx.html