作用域
作用域定义了一个代码块中名称的可见性。如果代码块中定义了一个局部变量,则其作用域包含该代码块。如果定义发生于函数代码块中,则其作用域会扩展到该函数所包含的任何代码块,除非有某个被包含代码块引入了对该名称的不同绑定。
当一个名称在代码块中被使用时,会由包含它的最近作用域来解析。对一个代码块可见的所有这种作用域的集合称为该代码块的环境。
一个作用域是一个 命名空间 可直接访问的 Python 程序的文本区域。这里的 “可直接访问” 意味着对名称的非限定引用(限定引用指点号表达式例如 math.pi)会尝试在命名空间中查找名称。
# 全局变量作用域为当前模块
a = '全局变量'
def f():
# print 内置名称作用域包含全局
print(f'print 函数的命名空间可以访问:{a}')
return f'f 的命名空间可以访问:{a}'
print(a)
print(f())
全局变量
print 函数的命名空间可以访问:全局变量
f 的命名空间可以访问:全局变量
# 全局变量作用域为当前模块
# 但被包含命名空间引入了同名的局部变量
a = '全局变量'
def f():
# f 中定义的局部变量
# 作用域为函数内部
a = '局部变量'
print(f'print 函数的命名空间可以访问:{a}')
return f'f 的命名空间可以访问:{a}'
print(a)
print(f())
全局变量
print 函数的命名空间可以访问:局部变量
f 的命名空间可以访问:局部变量
虽然作用域是静态地确定的,但它们会被动态地使用。嵌套作用域的搜索顺序:
- 最先搜索最内部作用域包含的局部名称
- 从最近的封闭作用域开始搜索作用域包含的名称
- 倒数第二个作用域包含当前模块的全局名称
- 最外面的作用域(最后搜索)是包含内置名称的命名空间
# 搜索最内部作用域名称 str
# 屏蔽上层作用域
def f():
str = 0
def f1():
str = 1
return str
return f1()
f(), str
(1, str)
# 搜索最近封闭作用域名称 str
# 屏蔽上层作用域
def f():
str = 0
def f1():
return str
return f1()
f(), str
(0, str)
# 搜索当前模块作用域名称 str
# 屏蔽上层作用域
str = '当前模块str'
def f():
def f1():
return str
return f1()
f()
'当前模块str'
# 搜索最外面作用域名称 str
# 删除前面对 str 的绑定
del str
# 注意,运行多次会将内置名称 str 都删除
def f():
def f1():
return str
return f1()
f()
str
可见,当前模块中的全局名称,最好不要和内置名称相同,它会屏蔽掉内置名称,从而不可以直接使用内置功能。内置名称如下:
import builtins
dir(builtins)
['ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'BlockingIOError',
'BrokenPipeError',
'BufferError',
'BytesWarning',
'ChildProcessError',
'ConnectionAbortedError',
'ConnectionError',
'ConnectionRefusedError',
'ConnectionResetError',
'DeprecationWarning',
'EOFError',
'Ellipsis',
'EnvironmentError',
'Exception',
'False',
'FileExistsError',
'FileNotFoundError',
'FloatingPointError',
'FutureWarning',
'GeneratorExit',
'IOError',
'ImportError',
'ImportWarning',
'IndentationError',
'IndexError',
'InterruptedError',
'IsADirectoryError',
'KeyError',
'KeyboardInterrupt',
'LookupError',
'MemoryError',
'ModuleNotFoundError',
'NameError',
'None',
'NotADirectoryError',
'NotImplemented',
'NotImplementedError',
'OSError',
'OverflowError',
'PendingDeprecationWarning',
'PermissionError',
'ProcessLookupError',
'RecursionError',
'ReferenceError',
'ResourceWarning',
'RuntimeError',
'RuntimeWarning',
'StopAsyncIteration',
'StopIteration',
'SyntaxError',
'SyntaxWarning',
'SystemError',
'SystemExit',
'TabError',
'TimeoutError',
'True',
'TypeError',
'UnboundLocalError',
'UnicodeDecodeError',
'UnicodeEncodeError',
'UnicodeError',
'UnicodeTranslateError',
'UnicodeWarning',
'UserWarning',
'ValueError',
'Warning',
'WindowsError',
'ZeroDivisionError',
'__IPYTHON__',
'__build_class__',
'__debug__',
'__doc__',
'__import__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'abs',
'all',
'any',
'ascii',
'bin',
'bool',
'breakpoint',
'bytearray',
'bytes',
'callable',
'chr',
'classmethod',
'compile',
'complex',
'copyright',
'credits',
'delattr',
'dict',
'dir',
'display',
'divmod',
'enumerate',
'eval',
'exec',
'filter',
'float',
'format',
'frozenset',
'get_ipython',
'getattr',
'globals',
'hasattr',
'hash',
'help',
'hex',
'id',
'input',
'int',
'isinstance',
'issubclass',
'iter',
'len',
'license',
'list',
'locals',
'map',
'max',
'memoryview',
'min',
'next',
'object',
'oct',
'open',
'ord',
'pow',
'print',
'property',
'range',
'repr',
'reversed',
'round',
'set',
'setattr',
'slice',
'sorted',
'staticmethod',
'str',
'sum',
'super',
'tuple',
'type',
'vars',
'zip']