Пространство имен функции python

/привет/мир/etc

Как известно, в 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() , '__spec__': None, '__annotations__': <>, '__builtins__': , 'name': '__spec__'> 

(Заметьте, в пространстве имен появилось имя name, использованное нами выше в качестве переменной в цикле for . И с именем name связано значение, присвоенное ему в цикле последним.)

Наше текущее пространство имен при вводе команд в интерактивном режиме Python — это глобальное пространство имен модуля __main__ . Поэтому словарь, возвращаемый функцией globals() и представляющий глобальное пространство имен, совпадает со словарем, возвращаемым locals() :

 >>> globals() , '__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', '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 .

Читайте также:  Sql database dump php

Следующие два вызова по сути одно и то же:

>>> 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 ord pow print property quit Use quit() or Ctrl-Z plus Return to exit range repr reversed round set setattr slice sorted staticmethod str sum super tuple type vars zip

Читайте также:  Javascript if key exist in array

Так, например, eval , any и all являются builtin_function_or_method , а вот filter , map и range являются экземплярами класса type , то есть, классами. (Да ведь это итераторы!)

Следующая попытка разрешить имя pi не удается, потому что это имя не определено в глобальном пространстве имен и не определено в модуле builtins :

>>> pi Traceback (most recent call last): File "", line 1, in NameError: name 'pi' is not defined 

Оно определено в модуле math . Импортируем этот модуль и проверим, что изменилось в текущем пространстве имен:

>>> import math >>> dir() ['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'math', 'name'] 

В текущем пространстве имен появилось имя math . Это имя указывает на модуль math :

В котором есть много интересного:

>>> dir(math) ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'ata nh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fm od', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc'] 

В том числе, интересующее нас имя pi , с которым связано число пи:

Мы даже можем его переопределить (хотя это хулиганство):

>>> math.pi = 123.123 >>> math.pi 123.123 

Вернемся теперь к вопросу о локальном пространстве имен. Чтобы функция locals() вернула словарь для локального пространства имен, нужно вызвать ее внутри нашей собственной функции, где текущее простраство имен — локальное пространство имен этой функции.

>>> def loc(): . x = 1 . y = 2 . print(locals() == globals()) . print(locals()) . print(globals()) . >>> loc() False  , '__spec__': None, '__annotations__': <>, '__builtins__': , 'name': '__spec__', 'math': < module 'math' (built-in)>, 'loc': > 

Теперь разница между locals() и globals() очевидна.

А в глобальном пространстве имен появилось имя loc , указывающее на определенную нами функцию. Вызовем ее по-другому:

>>> globals()['loc']() False  , '__spec__': None, '__annotations__': <>, '__builtins__': , 'name': '__spec__', 'math': < module 'math' (built-in)>, 'loc': > 

Можно вызвать и так (ведь на уровне модуля глобальное и локальное пространства имен совпадают):

>>> locals()['loc']() False  , '__spec__': None, '__annotations__': <>, '__builtins__': , 'name': '__spec__', 'math': < module 'math' (built-in)>, 'loc': > 

А как поживает число пи в модуле math ?

Читайте также:  Жирный текст с помощью CSS - "Нубекс"

Прекратим это безобразие и, пожалуй, закончим на сегодня:

Источник

Пространство имен Python

Разрешение Области Действия Legb

В этом руководстве мы узнаем о пространстве имен Python, области действия переменной и правилах разрешения области видимости переменной.

Что такое пространство имен Python?

Пространства имен Python — это контейнеры для сопоставления имен объектам. В Python все является объектом, и мы указываем имя объекта, чтобы мы могли получить к нему доступ позже.

Вы можете думать о пространстве имен как о словаре пар ключ-значение, где ключ — это имя переменной, а значение — связанный с ней объект.

В Python одновременно могут существовать несколько независимых пространств имен. Имена переменных можно повторно использовать в этих пространствах имен.

function_namespace = for_loop_namespace =

Давайте посмотрим на простой пример, где у нас есть несколько пространств имен.

пример

Типы пространств имен Python и жизненный цикл

Пространства имен Python можно разделить на четыре типа.

  1. Локальное пространство имен: функция, цикл for, блок try-except — некоторые примеры локального пространства. Удаляется, когда функция или блок кода завершают свое выполнение.
  2. Закрытое: когда функция определяется внутри функции. Жизненный цикл такой же, как и у локального.
  3. Глобальное: оно принадлежит скрипту python или текущему модулю. Глобальное пространство имен для модуля создается при чтении определения модуля. Как правило, пространства имен модулей также существуют до завершения работы интерпретатора.
  4. Встроенное: встроенное пространство имен создается при запуске интерпретатора Python и никогда не удаляется.

Область видимости переменной

Область видимости переменной Python определяет иерархию, в которой мы ищем переменную. Например, в приведенной выше программе переменные присутствуют в разных пространствах имен. Когда мы хотим получить доступ к значению переменной по ее имени, он ищется в иерархии пространства имен.

Правила разрешения(LEGB)

Переменные Python ищутся в следующем порядке пространств имен.

Local -> Enclosed -> Global -> Built-in

Это также называется правилом LEGB.

LEGB правило

Если имя не найдено в иерархии, возникает ошибка NameError.

Когда мы создаем объект или импортируем модуль, мы создаем для них отдельное пространство имен. Мы можем получить доступ к их переменным с помощью оператора точки.

>>> import math >>> >>> import numpy >>> >>> print(math.pi) 3.141592653589793 >>> print(numpy.pi) 3.141592653589793 >>> >>> obj = object() >>> print(obj.__doc__) The most base type >>>

Давайте посмотрим на пример, включающей все пространства имен.

x = 10 print(f'x is ') def outer(): x = 20 print(f'x is ') def inner(): x = 30 print(f'x is ') print(len("abc")) inner() outer()

Источник

Оцените статью