Python 命名空间及作用域

介绍Python命令空间及作用域。

在Python中包括三个独立的命名空间:localglobalbuiltin,所有信息保存在PyFrameObject中。

访问PyFrameObject

PyFrameObject对象是一个用于python虚拟机实现的内部对象,对应于可执行文件在执行时的栈帧,但python提供了getframe方法来访问该对象。

1
2
3
4
5
6
7
8
import sys

frame = sys._getframe()

print frame.f_code.co_name # 函数名称

print frame.f_locals #局部变量
print frame.f_globals #全局变量

module与命名空间

py文件可以视为一个module,它的作用不仅是为了代码复用,而且可以为整个系统划分命名空间。

在Python中,赋值语句会影响命名空间。

由于命名空间和变量函数的约束关系,Python中采用PyDictObject对象来存储该约束关系。

在一个module的内部,可能存在多个命名空间,每一个命名空间都与一个作用域对应。

作用域是指一段程序的正文区域,在这个区域里可能存在多个约束条件,但除了这个区域约束条件就不起作用了。

一个约束条件是否起作用,是由该约束在文本中的位置决定的,而不是动态决定,因此,Python是具有静态作用域

作用域

  • 一个函数定义了一个Local作用域;
  • 一个module定义了一个global作用域;
  • Python自身定义的作用域builtin作用域(内建函数dir,open,range等)。

名字引用是指在命名空间中查找一个名字所引用的对象,不允许越过module边界。

属性引用是指到对象的命名空间查找名字。

嵌套函数的命名空间

1
2
3
4
5
def compare(base, value):
return value > base

compare(10, 5)
compare(10, 20)

上面的例子中,会使用两次10来进行比较,Python中提供嵌套的方法只需要设置一次10即可。

1
2
3
4
5
6
7
def get_compare(base):
def real_compare(value):
return value > base

compare_with_10 = get_compare(10)
print compare_with_10(5) #False
print compare_with_10(20) #True

上面的例子形成了一个闭包,是将名字空间和函数捆绑后的结果。

1
2
3
4
5
6
7
8
def get_compare(base):
def real_compare(value, base=base):
return value > base

compare_with_10 = get_compare(10)
print compare_with_10(5) #False
print compare_with_10(20) #True
print compare_with_10(5, 1) #True

线程与module

在Python中,所有module是全局共享的。

Pyton虚拟机是对CPU的抽象,利用不同线程轮流使用虚拟机来实现多线程。

Python中使用GIL(Global Interpreter Lock)来实现线程同步。