На протяжении обучения Python мы использовали предопределенные функции Python, такие как print(), input(), type() и другие. В Python существует огромное количество функций, и не все они доступны напрямую из нового скрипта Python. Вместо этого они хранятся в отдельных файлах, называемых модулями. Чтобы использовать эти функции, нам нужно импортировать модуль, который их содержит. Это делается с помощью оператора import. Давайте проиллюстрируем это:
import math # Импортируем модуль math
print(math.pi) # Доступ к константе pi из модуля math
print(math.sqrt(16)) # Доступ к функции квадратного корня из модуля math
Эта программа выведет значение pi (3.141592653589793) и квадратный корень из 16 (4.0).
Мы также можем импортировать конкретные атрибуты или функции из модуля, используя оператор from...import:
from math import pi, sqrt # Импортируем только pi и sqrt из модуля math
print(pi) # Теперь мы можем использовать pi напрямую без указания имени модуля
print(sqrt(16)) # Аналогично, можем использовать sqrt напрямую
Вывод программы будет таким же, как и в предыдущем примере.
Иногда модули имеют длинные имена, и каждый раз вводить полное имя, когда мы хотим использовать функцию, может быть утомительно. Чтобы этого избежать, мы можем использовать ключевое слово as для присвоения модулю другого имени (псевдонима).
import math as m # Импортируем модуль math и переименовываем его в m
print(m.pi) # Теперь мы можем использовать короткий псевдоним
print(m.sqrt(16)) # Используем функцию sqrt через псевдоним
Вывод также будет 3.141592653589793 и 4.0, как и раньше.
В заключение, модули в Python подобны ящикам с инструментами, которые содержат предопределенные функции и переменные, которые мы можем импортировать и использовать в наших программах. Они помогают организовать код и сделать его более эффективным.
Как работают модули за кулисами
Когда вы импортируете модуль, Python выполняет некоторую работу за кулисами, которая может быть не сразу очевидна. Вот обзор того, что происходит, когда вы используете оператор import:
Поиск модуля:
Python сначала ищет модуль, проверяя пути, указанные в списке sys.path. Этот список включает текущий каталог, каталог встроенных пакетов Python и любые пути, указанные в переменной окружения PYTHONPATH. Если Python находит модуль, он переходит к следующим шагам. Если нет, то выбрасывается ModuleNotFoundError.
Инициализация модуля:
Как только файл модуля найден, Python создает новый объект модуля (types.ModuleType). Затем он загружает содержимое модуля в этот новый объект, выполняя весь код верхнего уровня в файле модуля. Это включает определения функций, классов, переменных и выполнение кода инициализации.
Кэширование модуля:
После инициализации модуль кэшируется в sys.modules (словарь). Этот шаг гарантирует, что когда тот же модуль импортируется снова в скрипте (или другими скриптами), Python не нужно заново искать и инициализировать модуль. Вместо этого он может использовать кэшированную версию. Ключом в этом словаре является имя модуля, а значением — объект модуля.
Добавление модуля в пространство имен импортера:
Наконец, Python добавляет имя модуля в пространство имен скрипта или модуля, который его импортировал. Имя ссылается на объект модуля, поэтому вы можете обращаться к функциям и переменным модуля, используя точечную нотацию.
Давайте проиллюстрируем это кодом:
import sys
import math
print(sys.path) # Путь, по которому Python ищет модули
print(sys.modules) # Кэшированные модули
print(math.sqrt(16)) # Доступ к функции из модуля math
sys.path выводит список каталогов, в которых Python ищет модули. sys.modules выводит словарь имен модулей (ключей) и соответствующих объектов модулей (значений).
Задание: Случайные числа
В мире криптографии случайные числа играют невероятно важную роль. Криптографические алгоритмы часто полагаются на генерацию последовательности случайных чисел для обеспечения безопасности данных.
В этом задании вам предстоит смоделировать простой генератор случайных чисел, который поможет нам понять случайность в более осязаемой форме. Python имеет встроенный модуль random, который содержит различные функции для генерации случайных чисел. Вам нужно использовать этот модуль, чтобы сгенерировать список из n случайных целых чисел между двумя заданными числами a и b. Однако случайность не должна быть по-настоящему случайной — нам нужно установить зерно генератора случайных чисел равным 42 для повторяемости эксперимента. Вы можете использовать функцию seed() для установки зерна и randint() для генерации случайного числа.
Первая строка ввода содержит три целых числа, разделенных пробелом: n, a и b. Числа a и b определяют диапазон (включительно), из которого должны выбираться случайные числа, а n определяет, сколько таких чисел вам нужно сгенерировать.
Программа должна вывести n случайных чисел, разделенных пробелом, сгенерированных в диапазоне [a, b] с фиксированным значением зерна 42.
Ввод
Вывод
10 1 100
82 15 4 95 36 32 29 18 95 14
5 1 5
1 1 3 2 2
3 10 20
20 11 10
Примечание: Поскольку мы устанавливаем зерно генератора случайных чисел равным 42, последовательность вывода должна оставаться неизменной при многократных запусках программы. Это свойство мы используем в тестировании, отладке и других сценариях, где необходим детерминированный вывод.