Свойства модулей в Python

Раздел: Основы Python -> Работа с модулями

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

Как получить полный список атрибутов модуля и обратиться к каждому из них?

Каждый модуль в Python представляет собой объект со своим пространством имён. Атрибутами модуля являются все имена, определённые на уровне модуля: переменные, функции, классы, а также встроенные атрибуты, такие как __name__, __doc__, __file__ и другие. Для доступа к атрибутам используется синтаксис module.attribute. Для динамического обращения применяются функции getattr(), hasattr(), setattr() и dir().

Наиболее эффективный способ получить все атрибуты модуля - вызвать dir(module) или обратиться к module.__dict__. Функция dir() возвращает отсортированный список строк с именами атрибутов, включая унаследованные от встроенного типа модуля. Словарь __dict__ содержит только те имена, которые определены непосредственно в модуле, и доступен для изменений.

import math
print(dir(math))          # список атрибутов модуля math
print(math.__dict__)      # словарь атрибутов модуля

Python module attributes (атрибуты модуля в python)

Для проверки наличия конкретного атрибута используется hasattr(module, name). Для чтения - getattr(module, name, default). Для установки - setattr(module, name, value).

import sys
print(hasattr(sys, 'version'))  # True
print(getattr(sys, 'version', 'не найден'))  # версия Python
setattr(sys, 'my_custom_attr', 42)
print(sys.my_custom_attr)       # 42

Python module version (версия модуля python)

Как получить список атрибутов, исключая встроенные?

Можно отфильтровать имена, начинающиеся с двойного подчёркивания, или использовать vars(module), которая возвращает словарь __dict__.

import mymodule
public = [attr for attr in dir(mymodule) if not attr.startswith('_')]
print(public)

Python cpp module (взаимодействие python с модулями c++)

Типичная ошибка:

При использовании from module import * импортируются только атрибуты, перечисленные в __all__. Если __all__ не определён, то импортируются все имена, не начинающиеся с подчёркивания. Это может привести к неожиданному загрязнению пространства имён. Решение - всегда явно определять __all__ в модуле.

Как получить информацию о модуле: имя, файл, документацию?

Модуль хранит метаданные во встроенных атрибутах: __name__ - имя модуля, __file__ - путь к файлу, __doc__ - строка документации, __package__ - имя пакета (для пакетов), __spec__ - объект спецификации модуля.

import os
print(os.__name__)    # 'os'
print(os.__file__)    # '.../os.py'
print(os.__doc__[:50])# первые 50 символов

Python module cv2 (модуль cv2 (opencv) в python)

Проблема:

У встроенных модулей (например, sys) атрибут __file__ может отсутствовать или быть пустым, так как они скомпилированы в интерпретатор. Проверка hasattr(module, '__file__') перед использованием предотвращает ошибки.

Как задать версию модуля и другие пользовательские атрибуты?

Обычно определением в модуле: __version__ = '1.0.0'. Также возможно присваивание из другого модуля через setattr().

# модуль mymodule.py
__version__ = '2.1.0'
__author__ = 'Василий Петров'

# из другого файла
import mymodule
print(mymodule.__version__)
setattr(mymodule, 'release_date', '2025-04-01')
print(mymodule.release_date)

Python encodings module (модуль encodings в python)

Предостережение:

Изменение атрибутов стандартных библиотечных модулей на лету может нарушить работу других частей кода или самого интерпретатора. Рекомендуется изменять только собственные модули.

Как работать с пакетами: атрибуты __path__ и __package__?

Пакет - это модуль, содержащий подмодули. Его атрибут __path__ указывает пути, где искать подпакеты, а __package__ содержит имя пакета. Для пакетов-пространств имён (namespace packages) __path__ может состоять из нескольких путей.

import xml
print(xml.__package__)   # 'xml'
print(xml.__path__)      # ['.../xml']

Platform module python (модуль platform в python)

Как контролировать, что экспортируется из модуля?

Определением списка __all__. Он влияет только на from module import * и на функцию dir() в некоторых контекстах.

# mymodule.py
__all__ = ['func1', 'ClassA']
def func1(): pass
class ClassA: pass
def internal(): pass   # не будет импортирован 
# другой файл from mymodule import * # func1 и ClassA доступны, internal - нет

Ошибка:

Забыть указать __all__ и случайно сделать видимой внутреннюю функцию. Решение - всегда явно определять публичный интерфейс.

- Python tkinter module (модуль tkinter в python)
- Python types module (модуль types в python)
- Python typing module (модуль typing в python)

Развёрнутые примеры работы с атрибутами модулей

Пример 1. Интроспекция модуля math

Получение списка всех атрибутов модуля math, фильтрация публичных, и просмотр значения одного из них.

Пример
import math

# все атрибуты
all_attrs = dir(math)
print("Всего атрибутов:", len(all_attrs))

# только публичные (не начинаются с _)
pub_attrs = [a for a in all_attrs if not a.startswith('_')]
print("Публичные:", pub_attrs[:10], "...")

# значение атрибута pi
print("pi =", getattr(math, 'pi'))  # 3.141592653589793
Всего атрибутов: 65
Публичные: ['acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'cbrt', 'ceil', 'comb'] ...
pi = 3.141592653589793

Пример 2. Создание модуля с пользовательскими атрибутами во время выполнения

Допустим, есть модуль config.py, в который динамически добавляются настройки из JSON-файла.

Пример
# config.py
import json

with open('settings.json', 'r') as f:
    settings = json.load(f)

for key, value in settings.items():
    globals()[key] = value

__all__ = list(settings.keys())
(при наличии settings.json, например {"db_host": "localhost", "db_port": 5432}, после импорта config будут доступны config.db_host и config.db_port)

Пример 3. Использование __all__ для ограничения экспорта

Создание модуля utils.py, где определены публичные и приватные функции.

Пример
# utils.py
__all__ = ['public_func1', 'PublicClass']

def public_func1():
    return "доступна"

def _private_helper():
    return "скрыта"

class PublicClass:
    pass
# другой файл
from utils import *
print(public_func1())     # работает
print(_private_helper)    # NameError не определена

Пример 4. Модификация атрибутов модуля во время выполнения

Изменение атрибута some_module.flag извне, что влияет на поведение функций модуля.

Пример
# controls.py
flag = False

def run():
    if flag:
        print("Активировано")
    else:
        print("Не активировано")

# main.py
import controls
controls.run()        # Не активировано
controls.flag = True
controls.run()        # Активировано
Не активировано
Активировано

Пример 5. Работа с __path__ в пакете-пространстве имён

Создание двух каталогов, каждый из которых содержит namespace_pkg/__init__.py. При импорте пакета namespace_pkg его путь объединяется.

Пример
import namespace_pkg
print(namespace_pkg.__path__)
# ['/path/to/first/namespace_pkg', '/path/to/second/namespace_pkg']
(зависит от структуры файловой системы)

Пример 6. Проверка существования атрибута с fallback

Безопасное получение версии модуля с использованием getattr.

Пример
import sys
version = getattr(sys, 'version_info', None)
if version:
    print(f"Python {version.major}.{version.minor}")
else:
    print("Не удалось получить версию")
Python 3.12

Пример 7. Использование __spec__ для получения подробной информации о загрузке модуля

Пример
import collections
spec = getattr(collections, '__spec__', None)
if spec:
    print("Имя:", spec.name)
    print("Оригинальное имя:", spec.origin)
    print("Подмодули:", spec.submodule_search_locations)
Имя: collections
Оригинальное имя: /usr/lib/python3.12/collections/__init__.py
Подмодули: ['/usr/lib/python3.12/collections']

Атрибуты модуля в Python - comments

En
Python module attributes (python)