W3docs

Модули Python

Узнайте, как работают модули Python: создавайте свои, импортируйте с псевдонимами, используйте from-import, изучайте стандартную библиотеку и sys.path.

Модуль — это файл, содержащий код Python: функции, классы и переменные, которые можно повторно использовать в нескольких программах. Модули являются основной единицей организации кода в Python: вместо того чтобы копировать логику между файлами, вы пишете её один раз, сохраняете в файл .py и импортируете там, где нужно. В этой главе рассматривается всё: от создания первого модуля до работы со стандартной библиотекой и понимания того, как Python находит модули во время выполнения.

Что такое модуль Python?

Любой файл .py является модулем. Когда вы пишете:

# greetings.py
def hello(name):
    return f"Hello, {name}!"

def goodbye(name):
    return f"Goodbye, {name}!"

PI = 3.14159

вы создали модуль с именем greetings. Имя модуля — это имя файла без расширения .py.

Модули могут содержать:

  • Функции — повторно используемые блоки логики (см. Функции Python)
  • Классы — шаблоны для объектов (см. Классы Python)
  • Переменные и константы — общие данные
  • Исполняемые операторы — код, который выполняется при импорте модуля или его прямом запуске

Импорт модуля

Используйте оператор import, за которым следует имя модуля (без расширения .py).

import greetings

print(greetings.hello("Alice"))    # Hello, Alice!
print(greetings.goodbye("Alice"))  # Goodbye, Alice!
print(greetings.PI)                # 3.14159

После import greetings все имена, определённые в greetings.py, доступны через префикс greetings.. Такая точечная нотация предотвращает конфликты имён — ваша собственная переменная PI не будет конфликтовать с greetings.PI.

Импорт конкретных имён с помощью from ... import

Если вам нужно одно или два имени, импортируйте их напрямую, чтобы использовать без префикса модуля.

from greetings import hello, PI

print(hello("Bob"))   # Hello, Bob!
print(PI)             # 3.14159

Импорт всего с помощью *

from greetings import *

Это помещает все публичные имена (те, что не начинаются с _) в текущее пространство имён. Избегайте этого в крупных программах: такой подход засоряет пространство имён и затрудняет определение того, откуда пришло то или иное имя.

Псевдонимы при импорте с помощью as

Длинные имена модулей неудобно вводить. Используйте as, чтобы создать более короткий псевдоним.

import greetings as gr

print(gr.hello("Carol"))   # Hello, Carol!

Псевдоним можно задать и для отдельных импортируемых имён:

from greetings import hello as hi

print(hi("Dave"))   # Hello, Dave!

Псевдонимы особенно распространены с популярными библиотеками:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

Функция dir()

dir(module) возвращает отсортированный список всех имён, определённых в модуле — быстрый способ узнать, что доступно.

import math
print(dir(math))
# ['__doc__', '__loader__', ..., 'acos', 'acosh', 'asin', ..., 'sqrt', 'tan', 'tanh', 'tau']

Вызовите dir() без аргументов, чтобы увидеть имена в текущей области видимости.

Переменная __name__

В каждом модуле есть встроенная переменная __name__. При импорте файла переменная __name__ принимает значение имени модуля. При прямом запуске файла переменная __name__ принимает значение строки "__main__".

Этот шаблон является стандартным способом написания кода, который выполняется только при запуске файла как скрипта, а не при его импорте в качестве библиотеки:

# greetings.py

def hello(name):
    return f"Hello, {name}!"

if __name__ == "__main__":
    # This block only runs when you execute: python greetings.py
    print(hello("World"))
import greetings   # The if-block does NOT run here

Этот шаблон используется практически в каждом нетривиальном файле Python, с которым вы столкнётесь.

Путь поиска модулей (sys.path)

Когда вы пишете import greetings, Python ищет модуль в списке директорий, хранящемся в sys.path:

  1. Директория запускаемого скрипта (или текущая директория в интерактивном режиме)
  2. Директории, указанные в переменной среды PYTHONPATH
  3. Директории стандартной библиотеки
  4. Директория site-packages (где живут сторонние пакеты, установленные через pip)
import sys
print(sys.path)
# ['/path/to/script', '/usr/lib/python3.11', ..., '/usr/lib/python3/dist-packages']

Вы можете добавить путь во время выполнения, но для хорошо структурированных проектов это редко требуется:

import sys
sys.path.append("/path/to/my/libs")

Стандартная библиотека Python

Python поставляется с большой стандартной библиотекой — сотнями модулей, охватывающих всё: от файлового ввода-вывода до сетевых протоколов и сжатия данных. Ничего устанавливать не нужно — просто импортируйте.

math — Математические функции

import math

print(math.sqrt(16))       # 4.0
print(math.pi)             # 3.141592653589793
print(math.factorial(5))   # 120
print(math.ceil(4.2))      # 5
print(math.floor(4.8))     # 4

См. Python Math для полного справочника.

random — Случайные числа

import random

print(random.randint(1, 10))          # random integer between 1 and 10
print(random.choice(["a", "b", "c"])) # random element
print(random.random())                 # float in [0.0, 1.0)

numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)
print(numbers)   # shuffled in place

datetime — Даты и время

import datetime

now = datetime.datetime.now()
print(now)                       # 2024-03-15 10:30:45.123456
print(now.year)                  # 2024
print(now.strftime("%B %d, %Y")) # March 15, 2024

today = datetime.date.today()
print(today)   # 2024-03-15

См. Python Dates для полного описания арифметики дат и форматирования.

os и sys — Операционная система и интерпретатор

import os

print(os.getcwd())              # current working directory
print(os.listdir("."))          # files in the current directory
os.makedirs("new_dir", exist_ok=True)  # create a directory
print(os.path.join("folder", "file.txt"))  # 'folder/file.txt'
import sys

print(sys.version)    # Python version string
print(sys.platform)   # 'linux', 'darwin', 'win32', etc.
sys.exit(0)           # terminate the program with exit code 0

json — Кодирование и декодирование JSON

import json

data = {"name": "Alice", "age": 30, "active": True}

# Python → JSON string
json_string = json.dumps(data, indent=2)
print(json_string)

# JSON string → Python
parsed = json.loads(json_string)
print(parsed["name"])   # Alice

См. Python JSON для чтения и записи файлов.

collections — Специализированные структуры данных

from collections import Counter, defaultdict

# Count occurrences
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counts = Counter(words)
print(counts)              # Counter({'apple': 3, 'banana': 2, 'cherry': 1})
print(counts.most_common(2))  # [('apple', 3), ('banana', 2)]

# Dict with default values
scores = defaultdict(int)
scores["Alice"] += 10
scores["Bob"] += 5
print(dict(scores))   # {'Alice': 10, 'Bob': 5}

См. Модуль collections в Python для namedtuple, deque и OrderedDict.

Создание собственного модуля

Базовая структура

Модули работают лучше всего, когда они хорошо справляются с одной задачей. Хорошее правило: если группа функций объединена общей темой, поместите их в отдельный файл.

# mathutils.py

def clamp(value, minimum, maximum):
    """Restrict value to the range [minimum, maximum]."""
    return max(minimum, min(value, maximum))

def average(numbers):
    """Return the arithmetic mean of a list of numbers."""
    if not numbers:
        raise ValueError("Cannot average an empty list")
    return sum(numbers) / len(numbers)

def is_prime(n):
    """Return True if n is a prime number."""
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True
# main.py
from mathutils import clamp, average, is_prime

print(clamp(15, 0, 10))          # 10
print(average([2, 4, 6, 8]))     # 5.0
print(is_prime(17))              # True

Строки документации в модулях

Добавьте строку документации на уровне модуля в самом начале файла. Такие инструменты, как help() и генераторы документации, используют её.

"""
mathutils.py — Utility functions for common mathematical operations.

Functions:
    clamp(value, minimum, maximum) -> number
    average(numbers) -> float
    is_prime(n) -> bool
"""

Переменные модуля: __all__

__all__ — это список имён, которые должны быть экспортированы при выполнении from module import *. Он также служит документацией о публичном API модуля.

# mathutils.py
__all__ = ["clamp", "average", "is_prime"]

def _helper():   # leading underscore marks it as private
    pass

Перезагрузка модуля

Python кэширует импортированные модули в sys.modules. Повторный импорт одного и того же модуля не выполняет его заново — Python возвращает кэшированную версию. В процессе интерактивной разработки или отладки можно принудительно выполнить перезагрузку:

import importlib
import greetings

importlib.reload(greetings)

Это в основном необходимо в сессиях REPL или Jupyter notebooks после редактирования файла модуля.

Распространённые ловушки

Циклические импорты

Если module_a импортирует module_b, а module_b импортирует module_a, возникает циклический импорт. Python может справляться с некоторыми циклическими импортами, но они запутывают код и часто указывают на проблему в архитектуре. Решение обычно состоит в реструктуризации кода: вынесите общую логику в третий модуль или отложите импорт внутрь функции.

Перекрытие модуля стандартной библиотеки

Если вы назовёте свой файл math.py, random.py или json.py, вы перекроете модуль стандартной библиотеки и сломаете любой код, который его импортирует. Используйте конкретные, описательные имена для своих модулей.

# BAD: naming your file math.py shadows the stdlib
# GOOD: name it mathutils.py or geometry.py

ImportError и ModuleNotFoundError

ModuleNotFoundError (подкласс ImportError) означает, что Python не смог найти модуль нигде на sys.path. Распространённые причины:

  • Опечатка в имени модуля
  • Модуль не установлен (pip install <package-name>)
  • Файл модуля находится в директории, которой нет в sys.path
try:
    import nonexistent_module
except ModuleNotFoundError as e:
    print(f"Import failed: {e}")
    # Import failed: No module named 'nonexistent_module'

Модули vs. пакеты

Модуль — это один файл .py. Пакет — это директория, содержащая несколько модулей и файл __init__.py. Пакеты позволяют строить более крупные библиотеки с иерархической структурой. См. Пакеты Python для полного описания.

Популярные сторонние модули

Помимо стандартной библиотеки, экосистема Python на PyPI насчитывает сотни тысяч пакетов. Устанавливайте их с помощью pip.

ПакетНазначение
numpyЧисленные вычисления, многомерные массивы
pandasАнализ и обработка данных
matplotlibВизуализация данных и построение графиков
requestsПростые HTTP-запросы
flask / djangoВеб-фреймворки
scikit-learnАлгоритмы машинного обучения
pytestФреймворк для тестирования

Практика

Практика
Which built-in variable tells you whether a Python file is being run directly or imported as a module?
Which built-in variable tells you whether a Python file is being run directly or imported as a module?
Was this page helpful?