Namespaces are one honking great idea — let's do more of those!
The Zen of Python, by Tim Peters
Как известно, в Python есть локальные пространства имен (внутри функции или класса, которые могут быть вложенными), глобальное (на уровне текущего модуля) и встроенное пространство имен модуля builtins. К последнему Python обращается в последнюю очередь, если искомое имя не находится в локальном и глобальном пространствах имен.
Посмотрим на пространства имен Python в интерактивном режиме.
C:_dev> python.exe
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> __name__
'__main__'
Это имя текущего модуля, в глобальном пространстве имен которого мы сейчас находимся. А функция dir() без аргументов покажет нам и другие имеющиеся в нем имена:
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
Попробуем увидеть, что за ними стоит. Нам помогут цикл for и eval():
>>> for name in dir(): print(name, eval(name), eval('type('+name+')'))
...
__annotations__ {}
__builtins__
__doc__ None
__loader__
__name__ __main__
__package__ None
__spec__ None
Приблизительно такую же информацию можно получить при помощи встроенной функции loclas(), которая возвращает словарь с ключами — именами текущего пространства имен:
>>> locals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__':
, '__spec__': None, '__annotations__': {}, '__builtins__': , 'name': '__spec__'}
(Заметьте, в пространстве имен появилось имя name, использованное нами выше в качестве переменной в цикле for. И с именем name связано значение, присвоенное ему в цикле последним.)
Наше текущее пространство имен при вводе команд в интерактивном режиме Python — это глобальное пространство имен модуля __main__. Поэтому словарь, возвращаемый функцией globals() и представляющий глобальное пространство имен, совпадает со словарем, возвращаемым locals():
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__':
, '__spec__': None, '__annotations__': {}, '__builtins__': , 'name': '__spec__'}
>>> locals() == globals()
True
Мы вернемся к разнице между locals() и globals() позднее. А пока посмотрим внимательно на то, что имеется в глобальном пространстве имен.
Под именем __builtins__ в глобальном пространстве имен имеется модуль builtins, который автоматически импортируется при запуске Python. Этот модуль содержит все встроенные функции и классы, в том числе такие знакомые, как int, float, list, а также все встроенные исключения (exceptions):
>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferEr
ror', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'Conne
ctionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsErr
or', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarni
ng', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'Lookup
Error', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplement
edError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionEr
ror', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'Syn
taxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalE
rror', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarni
ng', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__im
port__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray',
'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divm
od', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr&
#39;, 'ha
sh', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map',
'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr'
, 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'var
s', 'zip']
В нем есть имена функций dir, eval, locals и globals, которыми мы воспользовались выше так, как будто их имена известны в текущем пространстве имен. Дело в том, что имена, не найденные в глобальном пространстве имен, Python ищет в пространстве имен модуля builtins.
Следующие два вызова по сути одно и то же:
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'name']
>>> __builtins__.dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'name']
Кстати, любопытно, что не все так называемые встроенные функции Python на самом деле являются функциями; часть из них — классы. Это видно из следующего фрагмента:
>>> for name in dir(__builtins__): print(name, eval(name), eval('type('+name+')'))
...
ArithmeticError
AssertionError
AttributeError
BaseException
BlockingIOError
BrokenPipeError
BufferError
BytesWarning
ChildProcessError
ConnectionAbortedError
ConnectionError
ConnectionRefusedError
ConnectionResetError
DeprecationWarning
EOFError
Ellipsis Ellipsis
EnvironmentError
Exception
False False
FileExistsError
FileNotFoundError
FloatingPointError
FutureWarning
GeneratorExit
IOError
ImportError
ImportWarning
IndentationError
IndexError
InterruptedError
IsADirectoryError
KeyError
KeyboardInterrupt
LookupError
MemoryError
ModuleNotFoundError
NameError
None None
NotADirectoryError
NotImplemented NotImplemented
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
PermissionError
ProcessLookupError
RecursionError
ReferenceError
ResourceWarning
RuntimeError
RuntimeWarning
StopAsyncIteration
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TimeoutError
True True
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
WindowsError
ZeroDivisionError
__build_class__
__debug__ True
__doc__ None
__import__
__loader__
__name__ __main__
__package__ None
__spec__ None
abs
all
any
ascii
bin
bool
bytearray
bytes
callable
chr
classmethod
compile
complex
copyright Copyright (c) 2001-2017 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.
delattr
dict
dir
divmod
enumerate
eval
exec
exit Use exit() or Ctrl-Z plus Return to exit
filter
float
format
frozenset
getattr
globals
hasattr
hash
help Type help() for interactive help, or help(object) for help about object.
hex
id
input
int
isinstance
issubclass
iter
len
license Type license() to see the full license text
list
locals
map
max
memoryview
min
next
object
oct
open