Неймспейсы
В процессе работы мы создаем имена и связываем с ними какие-то объекты.
Пространство имен - это сопоставление имен переменных, функций, классов и реальных объектов в оперативной памяти.
Множество ссылок от все имен до объектов называется пространством имен.
В любой момент времени можно спросить у пространства имен, а связан ли с конкретным именем какой-нибудь объект.
Каждый вызов функции сопровождается созданием нового пространства имен.
Первое пространство имен создается, когда мы запускаем интерпретатор. Это пространство имен builtins содержит в себе встроенные функции и классы:
- int, str, float, bool;
- max, abs, id, ...
Второе пространство имен, которое создается это пространство main. Оно является глобальным и содержит в себе те имена, которые объявлены на самом верхнем уровне кода.
Локальные пространства имен не создаются, когда мы используем условный оператор или циклы:
x = 13 if x % 2 == 1: x += 1 print(x) #4
for i in range(5): x = i * i print(x) # 16
for i in []: y = i * i print(y) # NameError
Система модулей и импорт
Имя модуля это имя файла без расширения .py. Когда мы пишем import и модуль, мы берем файл с модулем и целиком его исполняем. Те имена, которые останутся в пространстве имен связанном с исполнением этого модуля, мы затем сможем импортировать.import exceptions7 print(exceptions7.greet("Student"))
Можно использовать import и в режиме работы интерпретатора.
>>> import exceptions7 Import is execution >>> exceptions7.greet <function greet at 0x00802DF8> >>> exceptions7.BadName <class 'exceptions7.BadName'>
Можно разграничивать код, который мы будем исполнять при импорте от кода, который нам бы не стоило выполнять при импорте. Для этого внутри модуля всегда доступно глобальное имя __name__. Таким образом для того чтобы понять, когда на импортируют, а когда запускают в интерпретаторе необходимо просто сравнить текущее имя с именем __main__.
def fib(k): if k == 0 or k == 1: return 1 else: return fib(k - 1) + fib(k - 2) if __name__ == "__main__": print(__name__) print(fib(31))
При импорте модуля происходит исполнение кода, однако это делается лишь единожды. Все глобальные имена, которые остались внутри данного неймспейса мы закрепим за нашим объектом модуля. При повторном импорте будет переиспользован старый объект для нашего модуля. Когда мы пишем import exceptions, интерпретатор идет и спрашивает у словаря sys.modules, а есть ли у тебя ключ 'exceptions'. Если ключа нет, тогда происходит исполнение модуля exceptions.
Таким образом любой модуль будет исполнен лишь единожды.
Если в sys.modules не было найдено имя модуля, то мы попробуем найти его в файле с расширением .py в текущей директории. Если и в текущей директории ничего не будет найдено, тогда мы пойдем искать его во внешние библиотеки. Для того чтобы понять в каком порядке это будет происходить можно вывести все пути в списке sys.path.
import sys for path in sys.path: print(path)
Также в языке Python мы можем импортировать не весь модуль целиком, а лишь какие-то имена из него.
from exceptions7 import BadName, greet as exc_greet import exceptions7 as exc def greet(): print("Greetings!") print(BadName) print(greet) greet() print(exc_greet("Student")) print(exc)
Чтобы импортировать все имена из модуля надо использовать звездочку.
from exceptions7 import * print(BadName) print(greet("Student"))
GREETING = "Hello, " class BadName(Exception): pass def greet(n): if n[0].isupper(): return GREETING + n else: raise BadName(n + " is inappropriate name") __all__ = ["BadName", "greet"]
Пакеты
Пакет - это удобный способ представления некоторого числа файлов в качестве одного модуля. Пакеты по сути это такие папки, которые могут вести себя как модули, которые мы тоже можем импортировать. Интерпретатор определяет является ли папка пакетом по наличию файла __init__.py внутри. Если внутри находится файл __init__.py, то он и исполняется при импорте.PyPI (Python Package Index) содержит в себе десятки тысяч пакетов предназначенных для решения различных задач. Пакеты устанавливаются с помощью утилиты pip. Для того, чтобы установить какую-нибудь библиотеку из Python Package Index (например пакет simple-crypt из следующей задачи), необходимо запустить команду pip install, например:
pip install simple-crypt
Комментариев нет:
Отправить комментарий