Python使用叫做命名空间的东西来记录变量的轨迹。命名空间是一个 key为变量名,value为变量值的字典
内置命名空间
Python内部使用的命名空间,包含内建函数名、异常类型名、内部常量名等等。
可以通过builtins
模块来查看内置命名空间(下列输出经过格式化处理):
>>> import builtins
>>> builtins.__dict__
{
'__name__': 'builtins',
'__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.",
'__package__': '',
'__loader__': < class '_frozen_importlib.BuiltinImporter' > ,
'__spec__': ModuleSpec(name = 'builtins', loader = < class '_frozen_importlib.BuiltinImporter' > ),
'__build_class__': < built - in function __build_class__ > ,
'__import__': < built - in function __import__ > ,
'abs': < built - in function abs > ,
'all': < built - in function all > ,
'any': < built - in function any > ,
'ascii': < built - in function ascii > ,
'bin': < built - in function bin > ,
'breakpoint': < built - in function breakpoint > ,
'callable': < built - in function callable > ,
'chr': < built - in function chr > ,
'compile': < built - in function compile > ,
'delattr': < built - in function delattr > ,
'dir': < built - in function dir > ,
'divmod': < built - in function divmod > ,
'eval': < built - in function eval > ,
'exec': < built - in function exec > ,
'format': < built - in function format > ,
'getattr': < built - in function getattr > ,
'globals': < built - in function globals > ,
'hasattr': < built - in function hasattr > ,
'hash': < built - in function hash > ,
'hex': < built - in function hex > ,
'id': < built - in function id > ,
'input': < built - in function input > ,
'isinstance': < built - in function isinstance > ,
'issubclass': < built - in function issubclass > ,
'iter': < built - in function iter > ,
'len': < built - in function len > ,
'locals': < built - in function locals > ,
'max': < built - in function max > ,
'min': < built - in function min > ,
'next': < built - in function next > ,
'oct': < built - in function oct > ,
'ord': < built - in function ord > ,
'pow': < built - in function pow > ,
'print': < built - in function print > ,
'repr': < built - in function repr > ,
'round': < built - in function round > ,
'setattr': < built - in function setattr > ,
'sorted': < built - in function sorted > ,
'sum': < built - in function sum > ,
'vars': < built - in function vars > ,
'None': None,
'Ellipsis': Ellipsis,
'NotImplemented': NotImplemented,
'False': False,
'True': True,
'bool': < class 'bool' > ,
'memoryview': < class 'memoryview' > ,
'bytearray': < class 'bytearray' > ,
'bytes': < class 'bytes' > ,
'classmethod': < class 'classmethod' > ,
'complex': < class 'complex' > ,
'dict': < class 'dict' > ,
'enumerate': < class 'enumerate' > ,
'filter': < class 'filter' > ,
'float': < class 'float' > ,
'frozenset': < class 'frozenset' > ,
'property': < class 'property' > ,
'int': < class 'int' > ,
'list': < class 'list' > ,
'map': < class 'map' > ,
'object': < class 'object' > ,
'range': < class 'range' > ,
'reversed': < class 'reversed' > ,
'set': < class 'set' > ,
'slice': < class 'slice' > ,
'staticmethod': < class 'staticmethod' > ,
'str': < class 'str' > ,
'super': < class 'super' > ,
'tuple': < class 'tuple' > ,
'type': < class 'type' > ,
'zip': < class 'zip' > ,
'__debug__': True,
'BaseException': < class 'BaseException' > ,
'Exception': < class 'Exception' > ,
'TypeError': < class 'TypeError' > ,
'StopAsyncIteration': < class 'StopAsyncIteration' > ,
'StopIteration': < class 'StopIteration' > ,
'GeneratorExit': < class 'GeneratorExit' > ,
'SystemExit': < class 'SystemExit' > ,
'KeyboardInterrupt': < class 'KeyboardInterrupt' > ,
'ImportError': < class 'ImportError' > ,
'ModuleNotFoundError': < class 'ModuleNotFoundError' > ,
'OSError': < class 'OSError' > ,
'EnvironmentError': < class 'OSError' > ,
'IOError': < class 'OSError' > ,
'WindowsError': < class 'OSError' > ,
'EOFError': < class 'EOFError' > ,
'RuntimeError': < class 'RuntimeError' > ,
'RecursionError': < class 'RecursionError' > ,
'NotImplementedError': < class 'NotImplementedError' > ,
'NameError': < class 'NameError' > ,
'UnboundLocalError': < class 'UnboundLocalError' > ,
'AttributeError': < class 'AttributeError' > ,
'SyntaxError': < class 'SyntaxError' > ,
'IndentationError': < class 'IndentationError' > ,
'TabError': < class 'TabError' > ,
'LookupError': < class 'LookupError' > ,
'IndexError': < class 'IndexError' > ,
'KeyError': < class 'KeyError' > ,
'ValueError': < class 'ValueError' > ,
'UnicodeError': < class 'UnicodeError' > ,
'UnicodeEncodeError': < class 'UnicodeEncodeError' > ,
'UnicodeDecodeError': < class 'UnicodeDecodeError' > ,
'UnicodeTranslateError': < class 'UnicodeTranslateError' > ,
'AssertionError': < class 'AssertionError' > ,
'ArithmeticError': < class 'ArithmeticError' > ,
'FloatingPointError': < class 'FloatingPointError' > ,
'OverflowError': < class 'OverflowError' > ,
'ZeroDivisionError': < class 'ZeroDivisionError' > ,
'SystemError': < class 'SystemError' > ,
'ReferenceError': < class 'ReferenceError' > ,
'MemoryError': < class 'MemoryError' > ,
'BufferError': < class 'BufferError' > ,
'Warning': < class 'Warning' > ,
'UserWarning': < class 'UserWarning' > ,
'DeprecationWarning': < class 'DeprecationWarning' > ,
'PendingDeprecationWarning': < class 'PendingDeprecationWarning' > ,
'SyntaxWarning': < class 'SyntaxWarning' > ,
'RuntimeWarning': < class 'RuntimeWarning' > ,
'FutureWarning': < class 'FutureWarning' > ,
'ImportWarning': < class 'ImportWarning' > ,
'UnicodeWarning': < class 'UnicodeWarning' > ,
'BytesWarning': < class 'BytesWarning' > ,
'ResourceWarning': < class 'ResourceWarning' > ,
'ConnectionError': < class 'ConnectionError' > ,
'BlockingIOError': < class 'BlockingIOError' > ,
'BrokenPipeError': < class 'BrokenPipeError' > ,
'ChildProcessError': < class 'ChildProcessError' > ,
'ConnectionAbortedError': < class 'ConnectionAbortedError' > ,
'ConnectionRefusedError': < class 'ConnectionRefusedError' > ,
'ConnectionResetError': < class 'ConnectionResetError' > ,
'FileExistsError': < class 'FileExistsError' > ,
'FileNotFoundError': < class 'FileNotFoundError' > ,
'IsADirectoryError': < class 'IsADirectoryError' > ,
'NotADirectoryError': < class 'NotADirectoryError' > ,
'InterruptedError': < class 'InterruptedError' > ,
'PermissionError': < class 'PermissionError' > ,
'ProcessLookupError': < class 'ProcessLookupError' > ,
'TimeoutError': < class 'TimeoutError' > ,
'open': < built - in function open > ,
'quit': Use quit() or Ctrl - Z plus Return to exit,
'exit': Use exit() or Ctrl - Z plus Return to exit,
'copyright': Copyright(c) 2001 - 2019 Python Software Foundation.
All Rights Reserved.
Copyright(c) 2000 BeOpen.com.
All Rights Reserved.
Copyright(c) 1995 - 2001 Corporation
for National Research Initiatives.
All Rights Reserved.
Copyright(c) 1991 - 1995 Stichting Mathematisch Centrum,
Amsterdam.
All Rights Reserved.,
'credits': Thanks to CWI,
CNRI,
BeOpen.com,
Zope Corporation and a cast of thousands
for supporting Python development.See www.python.org
for more information.,
'license': Type license() to see the full license text,
'help': Type help() for interactive help,
or help(object) for help about object.,
'_': None
}
Python内置命名空间的作用域是全局的,这里的全局指的是Python内的全局,而不是某个模块的全局,在任意Python代码中都可以使用内置命名空间中的函数、类和常量,因此,其余各级命名空间中的对象在命名时,不允许出现和内置命名空间已有的名称重名。
相关文档:
- builtins --- 内建对象 — Python 3.7.12 文档
- 内置函数 — Python 3.7.12 文档
- 内置常量 — Python 3.7.12 文档
全局命名空间
这里全局指的是一个模块的全局,每个.py文件都是一个Python模块,每个模块都有自己命名空间,叫做全局命名空间。
全局命名空间记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
全局命名空间作用域在模块内部,如果要在其它模块使用时,需要先导入(import)此模块,然后以
可以通过内建函数globals()
访问全局命名空间
局部命名空间
模块中的每个函数都是一个局部,拥有一个局部命名空间。
局部命名空间的作用域也在全局命名空间的作用域之中,并且局部命名空间可以使用全局命名空间中已有的名称。
如果需要在局部命名空间使用全局命名空间的变量,比如全局变量x
,分读取和修改两种情况:
- 读取
在局部命名空间,如果没有创建新的变量x,则调用x时默认使用的就是全局命名空间中的x - 修改
在局部命名空间,直接对x赋值,只会创建一个局部变量x。要修改全局变量x则需要先在局部命空间中使用global
关键字将x声明为变量:global x
,然后再对x赋值。
名称查找顺序
在函数中需要使用变量a,那查找变量a的顺序如下:
1、先查找局部命名空间
有没有定义a这个局部变量
或参数
,有则停止查询;没有则向上查找全局命名空间
2、查找全局命名空间
有没有定义a这个变量
、函数
或类
,有则停止查询;没有则查找内置命名空间
3、内置命名空间有a这个函数
或变量
则停止查询,否则抛出NameError
异常
可以通过内建函数locals()
访问局部命名空间
闭包命名空间
闭包的定义:内部函数包含对外部作用域而非全局作用域变量的引用,该内部函数称为闭包函数
函数中可以嵌套函数,嵌套函数就是闭包函数,其所在的命名空间就是闭包命名命名空间。
闭包命名空间和局部命名空间类似,只是其级别更低,作用域更小,只在嵌套函数内生效。
假设局部命名空间有变量x,在嵌套函数中可以直接对x进行读取和修改;如果需要重新创建一个同名变量,则需要先用nonlocal
关键字声明:nonlocal x
,再对x赋值。
在闭包函数中也可以使用使用global
关键字,直接修改全局变量。