Системный модуль Python: работа с библиотекой sys

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

Использование библиотеки sys в Python

Модуль sys предоставляет доступ к переменным и функциям, взаимодействующим с интерпретатором Python. Он включает средства для работы с аргументами командной строки, потоками ввода-вывода, путями поиска модулей, управлением рекурсией и сборкой мусора. Рассмотрим основные приёмы работы.

Как получить аргументы командной строки в Python?

Список sys.argv содержит аргументы, переданные скрипту. Первый элемент - имя скрипта, остальные - аргументы. Это самый простой способ передачи параметров.

import sys
print("Имя скрипта:", sys.argv[0])
for i, arg in enumerate(sys.argv[1:], 1):
    print(f"Аргумент {i}: {arg}")

библиотека os python (библиотека os для python)

Пример запуска: python script.py hello world выведет:

Имя скрипта: script.py
Аргумент 1: hello
Аргумент 2: world

библиотека sys python (библиотека sys в python)

Типичные проблемы:

  • Аргументы всегда строки. Необходимо преобразовывать в числа, если требуется числовой ввод.
  • Если скрипт запущен с неверным числом аргументов, нужно проверять длину len(sys.argv).
  • Имя скрипта может быть полным путём; для получения только имени используйте os.path.basename(sys.argv[0]).

Как завершить программу с кодом ошибки?

Функция sys.exit([code]) вызывает SystemExit. По умолчанию код 0 (успех). Ненулевой код означает ошибку.

import sys
if len(sys.argv) < 2:
    sys.exit("Требуется хотя бы один аргумент")  # код 1
sys.exit(0)

Можно передать строку или число.

Ошибка: при передаче строки код возврата становится 1, но строка выводится в stderr. Используйте sys.exit(1) для стандартного кода.

Как добавить каталог для поиска модулей?

Список sys.path определяет пути импорта. Добавление пути выполняется так:

import sys
sys.path.insert(0, '/home/user/mymodules')
sys.path.append('/another/path')

Однако постоянные изменения лучше выполнять через переменную окружения PYTHONPATH.

Проблема: изменение sys.path во время выполнения может нарушить порядок поиска и привести к путанице, особенно если используются относительные импорты.

Как оценить размер объекта?

sys.getsizeof(object) возвращает размер объекта в байтах (только память самого объекта, без учёта вложенных ссылок).

import sys
a = [1, 2, 3]
print(sys.getsizeof(a))  # 88 (может отличаться)
b = {'key': 'value'}
print(sys.getsizeof(b))  # 184

Нюанс: для контейнеров возвращается только размер контейнера. Для полного размера используйте pympler.asizeof.

Как изменить максимальную глубину рекурсии?

sys.setrecursionlimit(limit) устанавливает новый лимит рекурсивных вызовов. По умолчанию 1000.

import sys
sys.setrecursionlimit(5000)
def rec(n):
    if n == 0: return
    rec(n-1)
rec(2000)  # успешно

Опасность: слишком высокий лимит может вызвать переполнение стека (Segmentation fault) и аварийное завершение Python. Рекомендуется переписывать рекурсию в итерацию, если глубина может быть большой.

Как перенаправить стандартный вывод?

Объекты sys.stdout и sys.stderr можно временно заменить другими файловыми объектами.

import sys, io
original_stdout = sys.stdout
sys.stdout = io.StringIO()
print("Этот текст попадёт в буфер")
output = sys.stdout.getvalue()
sys.stdout = original_stdout
print("Буфер содержит:", repr(output))

Аналогично для stderr.

Ошибка: забыть восстановить sys.stdout - последующий вывод исчезнет. Рекомендуется использовать контекстный менеджер.

Как узнать версию Python и платформу?

sys.version содержит строку с информацией о версии. sys.platform - имя ОС.

import sys
print(sys.version)   # 3.12.0 (tags/v3.12.0:...)
print(sys.platform)  # win32 или linux

Полезно для кроссплатформенных проверок.

Тонкость: sys.platform не различает дистрибутивы Linux. Для детальной информации используйте модуль platform.

Расширенные примеры работы с модулем sys

Первый пример: динамическое добавление кастомного импортёра через sys.meta_path.

Пример
import sys
import importlib.abc

class MyLoader(importlib.abc.Loader):
    def create_module(self, spec):
        return None
    def exec_module(self, module):
        module.greet = lambda: "Привет!"

sys.meta_path.insert(0, MyLoader())
import my_custom_module
print(my_custom_module.greet())
Привет!

Второй пример: трассировка вызовов функций с помощью sys.settrace.

Пример
import sys
def trace(frame, event, arg):
    if event == 'call':
        print(f"Вызов {frame.f_code.co_name} в {frame.f_lineno}")
    return trace

sys.settrace(trace)
def outer():
    inner()
def inner():
    pass
outer()
sys.settrace(None)
Вызов outer в ...
Вызов inner в ...

Третий пример: мониторинг событий безопасности через sys.audithook.

Пример
import sys
def my_audit(event, args):
    if event in ('import', 'open'):
        print(f"Событие: {event}, аргументы: {args}")
sys.addaudithook(my_audit)
import os
open('temp.txt', 'w').close()
Событие: import, аргументы: ('os', None, None, None)
Событие: open, аргументы: ('temp.txt', 'w', ...)

Четвертый пример: получение размера объекта с учётом вложенных ссылок с помощью sys.getsizeof и дополнительной логики (неполный аналог pympler).

Пример
import sys
def total_size(obj, seen=None):
    if seen is None:
        seen = set()
    obj_id = id(obj)
    if obj_id in seen:
        return 0
    seen.add(obj_id)
    size = sys.getsizeof(obj)
    if isinstance(obj, dict):
        for k, v in obj.items():
            size += total_size(k, seen) + total_size(v, seen)
    elif isinstance(obj, (list, tuple, set, frozenset)):
        for item in obj:
            size += total_size(item, seen)
    return size

data = {'a': [1, 2, {'b': 3}], 'c': 'test'}
print(total_size(data))
(число, зависящее от интерпретатора)

Пятый пример: использование sys.getrefcount для подсчёта ссылок на объект.

Пример
import sys
a = []
print(sys.getrefcount(a))  # минимум 2 (глобальная переменная и параметр)
b = a
print(sys.getrefcount(a))  # 3
2
3

Шестой пример: работа с sys.executable и sys.prefix для определения пути к интерпретатору и установочному каталогу.

Пример
import sys
print("Интерпретатор:", sys.executable)
print("Префикс:", sys.prefix)
print("Префикс для пользовательских пакетов:", sys.exec_prefix)
Интерпретатор: C:\Python312\python.exe
Префикс: C:\Python312
Префикс для пользовательских пакетов: C:\Python312

Библиотека sys в Python - comments

En
библиотека sys python (python)