library.md
1> **Источник:** https://python-all.ru/3.1/faq/library.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [Часто задаваемые вопросы по библиотекам и расширениям](https://python-all.ru/3.1/faq/library.html#id2)89Содержание1011- [FAQ по библиотекам и расширениям](https://python-all.ru/3.1/faq/library.html#library-and-extension-faq)1213 - [Общие вопросы по библиотекам](https://python-all.ru/3.1/faq/library.html#general-library-questions)1415 - [Как найти модуль или приложение для выполнения задачи X?](https://python-all.ru/3.1/faq/library.html#how-do-i-find-a-module-or-application-to-perform-task-x)16 - [Где находится исходный файл math.py (socket.py, regex.py и т.д.)?](https://python-all.ru/3.1/faq/library.html#where-is-the-math-py-socket-py-regex-py-etc-source-file)17 - [Как сделать скрипт Python исполняемым в Unix?](https://python-all.ru/3.1/faq/library.html#how-do-i-make-a-python-script-executable-on-unix)18 - [Существует ли пакет curses/termcap для Python?](https://python-all.ru/3.1/faq/library.html#is-there-a-curses-termcap-package-for-python)19 - [Есть ли в Python эквивалент onexit() из C?](https://python-all.ru/3.1/faq/library.html#is-there-an-equivalent-to-c-s-onexit-in-python)20 - [Почему не работают мои обработчики сигналов?](https://python-all.ru/3.1/faq/library.html#why-don-t-my-signal-handlers-work)21 - [Типовые задачи](https://python-all.ru/3.1/faq/library.html#common-tasks)2223 - [Как протестировать программу или компонент Python?](https://python-all.ru/3.1/faq/library.html#how-do-i-test-a-python-program-or-component)24 - [Как создать документацию из строк документации?](https://python-all.ru/3.1/faq/library.html#how-do-i-create-documentation-from-doc-strings)25 - [Как получить одиночное нажатие клавиши?](https://python-all.ru/3.1/faq/library.html#how-do-i-get-a-single-keypress-at-a-time)26 - [Потоки](https://python-all.ru/3.1/faq/library.html#threads)2728 - [Как программировать с использованием потоков?](https://python-all.ru/3.1/faq/library.html#how-do-i-program-using-threads)29 - [Ни один из моих потоков не запускается: почему?](https://python-all.ru/3.1/faq/library.html#none-of-my-threads-seem-to-run-why)30 - [Как распределить работу между несколькими рабочими потоками?](https://python-all.ru/3.1/faq/library.html#how-do-i-parcel-out-work-among-a-bunch-of-worker-threads)31 - [Какие виды изменения глобальных значений являются потокобезопасными?](https://python-all.ru/3.1/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe)32 - [Нельзя ли избавиться от глобальной блокировки интерпретатора (GIL)?](https://python-all.ru/3.1/faq/library.html#can-t-we-get-rid-of-the-global-interpreter-lock)33 - [Ввод и вывод](https://python-all.ru/3.1/faq/library.html#input-and-output)3435 - [Как удалить файл? (И другие вопросы о файлах...)](https://python-all.ru/3.1/faq/library.html#how-do-i-delete-a-file-and-other-file-questions)36 - [Как скопировать файл?](https://python-all.ru/3.1/faq/library.html#how-do-i-copy-a-file)37 - [Как читать (или записывать) двоичные данные?](https://python-all.ru/3.1/faq/library.html#how-do-i-read-or-write-binary-data)38 - [Не удаётся использовать os.read() на канале, созданном с помощью os.popen(); почему?](https://python-all.ru/3.1/faq/library.html#i-can-t-seem-to-use-os-read-on-a-pipe-created-with-os-popen-why)39 - [Как получить доступ к последовательному порту (RS232)?](https://python-all.ru/3.1/faq/library.html#how-do-i-access-the-serial-rs232-port)40 - [Почему закрытие sys.stdout (stdin, stderr) на самом деле не закрывает его?](https://python-all.ru/3.1/faq/library.html#why-doesn-t-closing-sys-stdout-stdin-stderr-really-close-it)41 - [Сетевое и интернет-программирование](https://python-all.ru/3.1/faq/library.html#network-internet-programming)4243 - [Какие существуют инструменты для работы с WWW в Python?](https://python-all.ru/3.1/faq/library.html#what-www-tools-are-there-for-python)44 - [Как имитировать отправку CGI-формы (METHOD=POST)?](https://python-all.ru/3.1/faq/library.html#how-can-i-mimic-cgi-form-submission-method-post)45 - [Какой модуль использовать для генерации HTML?](https://python-all.ru/3.1/faq/library.html#what-module-should-i-use-to-help-with-generating-html)46 - [Как отправить письмо из скрипта Python?](https://python-all.ru/3.1/faq/library.html#how-do-i-send-mail-from-a-python-script)47 - [Как избежать блокировки в методе connect() сокета?](https://python-all.ru/3.1/faq/library.html#how-do-i-avoid-blocking-in-the-connect-method-of-a-socket)48 - [Базы данных](https://python-all.ru/3.1/faq/library.html#databases)4950 - [Существуют ли интерфейсы к пакетам баз данных в Python?](https://python-all.ru/3.1/faq/library.html#are-there-any-interfaces-to-database-packages-in-python)51 - [Как реализовать постоянные объекты в Python?](https://python-all.ru/3.1/faq/library.html#how-do-you-implement-persistent-objects-in-python)52 - [Если моя программа аварийно завершается с открытой базой данных bsddb (или anydbm), она повреждается. Почему?](https://python-all.ru/3.1/faq/library.html#if-my-program-crashes-with-a-bsddb-or-anydbm-database-open-it-gets-corrupted-how-come)53 - [Я попытался открыть файл Berkeley DB, но bsddb выдаёт bsddb.error: (22, 'Invalid argument'). Помогите! Как восстановить данные?](https://python-all.ru/3.1/faq/library.html#i-tried-to-open-berkeley-db-file-but-bsddb-produces-bsddb-error-22-invalid-argument-help-how-can-i-restore-my-data)54 - [Математика и численные методы](https://python-all.ru/3.1/faq/library.html#mathematics-and-numerics)5556 - [Как генерировать случайные числа в Python?](https://python-all.ru/3.1/faq/library.html#how-do-i-generate-random-numbers-in-python)5758## [Общие вопросы по библиотекам](https://python-all.ru/3.1/faq/library.html#id3)5960### [Как найти модуль или приложение для выполнения задачи X?](https://python-all.ru/3.1/faq/library.html#id4)6162Проверьте [*Справочник по библиотеке*](https://python-all.ru/3.1/library/index.html#library-index), чтобы узнать, есть ли подходящий модуль в стандартной библиотеке. (Со временем вы выучите, что есть в стандартной библиотеке, и сможете пропустить этот шаг.)6364Для сторонних пакетов выполните поиск в [Python Package Index](https://python-all.ru/3.1/faq/library.html) или воспользуйтесь [Google](https://python-all.ru/3.1/faq/library.html) или другой поисковой системой. Обычно поиск по «Python» с одним-двумя ключевыми словами по вашей теме находит что-нибудь полезное.6566### [Где находится исходный файл math.py (socket.py, regex.py и т. д.)?](https://python-all.ru/3.1/faq/library.html#id5)6768Если вы не можете найти исходный файл для модуля, возможно, это встроенный или динамически загружаемый модуль, реализованный на C, C++ или другом компилируемом языке. В этом случае у вас может не быть исходного файла, или он может быть, например, mathmodule.c, где-то в каталоге исходных текстов C (а не в пути Python).6970В Python существует (как минимум) три вида модулей:71721. модули, написанные на Python (.py);732. модули, написанные на C и динамически загружаемые (.dll, .pyd, .so, .sl и т. д.);743. модули, написанные на C и связанные с интерпретатором; чтобы получить их список, введите:7576 ```python77 import sys78 print(sys.builtin_module_names)79 ```8081### [Как сделать скрипт Python исполняемым в Unix?](https://python-all.ru/3.1/faq/library.html#id6)8283Нужно сделать две вещи: установить исполняемый режим для файла скрипта и убедиться, что первая строка начинается с `#!`, за которым следует путь к интерпретатору Python.8485Первый способ: выполнить `chmod +x scriptfile` или, возможно, `chmod 755 scriptfile`.8687Второе можно сделать несколькими способами. Самый простой – написать8889```python90#!/usr/local/bin/python91```9293в самой первой строке файла, указав путь к установленному на вашей платформе интерпретатору Python.9495Если вы хотите, чтобы скрипт не зависел от расположения интерпретатора Python, вы можете использовать программу «env». Почти все варианты Unix поддерживают следующее, при условии, что интерпретатор Python находится в каталоге, указанном в переменной $PATH пользователя:9697```python98#!/usr/bin/env python99```100101*Не* делайте этого для CGI-скриптов. Переменная $PATH для CGI-скриптов часто очень мала, поэтому необходимо использовать фактический абсолютный путь к интерпретатору.102103Иногда окружение пользователя настолько заполнено, что программа /usr/bin/env не срабатывает; или программы env вообще нет. В этом случае можно попробовать следующий трюк (от Алекса Резински):104105```python106#! /bin/sh107""":"108exec python $0 ${1+"$@"}109"""110```111112Небольшой недостаток в том, что при этом определяется строка документации \_\_doc\_\_ скрипта. Однако это можно исправить, добавив113114```python115__doc__ = """...Whatever..."""116```117118### [Существует ли пакет curses/termcap для Python?](https://python-all.ru/3.1/faq/library.html#id7)119120Для вариантов Unix: стандартный дистрибутив исходных текстов Python поставляется с модулем curses в подкаталоге `Modules/`, хотя по умолчанию он не компилируется (обратите внимание, что он недоступен в дистрибутиве Windows – модуля curses для Windows не существует).121122Модуль curses поддерживает базовые возможности curses, а также многие дополнительные функции из ncurses и SYSV curses, такие как цвет, поддержка альтернативных наборов символов, pad'ы и поддержка мыши. Это означает, что модуль несовместим с операционными системами, имеющими только BSD curses, но в настоящее время, похоже, нет поддерживаемых ОС, попадающих в эту категорию.123124Для Windows: используйте [модуль consolelib](https://python-all.ru/3.1/faq/library.html).125126### [Есть ли в Python аналог onexit() из C?](https://python-all.ru/3.1/faq/library.html#id8)127128Модуль [`atexit`](https://python-all.ru/3.1/library/atexit.html#module-atexit) предоставляет функцию register, аналогичную C'овской onexit.129130### [Почему не работают мои обработчики сигналов?](https://python-all.ru/3.1/faq/library.html#id9)131132Самая распространённая проблема – обработчик сигнала объявлен с неправильным списком аргументов. Он вызывается как133134```python135handler(signum, frame)136```137138поэтому он должен быть объявлен с двумя аргументами:139140```python141def handler(signum, frame):142 ...143```144145## [Типовые задачи](https://python-all.ru/3.1/faq/library.html#id10)146147### [Как тестировать программу или компонент Python?](https://python-all.ru/3.1/faq/library.html#id11)148149В состав Python входят два фреймворка для тестирования. Модуль [`doctest`](https://python-all.ru/3.1/library/doctest.html#module-doctest) находит примеры в строках документации модуля и запускает их, сравнивая вывод с ожидаемым результатом, указанным в docstring.150151Модуль [`unittest`](https://python-all.ru/3.1/library/unittest.html#module-unittest) – это более продвинутый фреймворк для тестирования, созданный по образцу фреймворков Java и Smalltalk.152153Для тестирования полезно писать программу так, чтобы её можно было легко тестировать с помощью хорошего модульного дизайна. Программа должна почти всю функциональность инкапсулировать в функции или методы классов – и это иногда имеет удивительный и приятный эффект: программа работает быстрее (потому что доступ к локальным переменным быстрее, чем к глобальным). Кроме того, программа должна избегать зависимости от изменения глобальных переменных, так как это делает тестирование гораздо более сложным.154155«Глобальная основная логика» вашей программы может быть такой же простой, как156157```python158if __name__ == "__main__":159 main_logic()160```161162в конце главного модуля программы.163164Как только ваша программа организована как управляемая совокупность функций и поведений классов, следует написать тестовые функции, которые проверяют эти поведения. Набор тестов можно связать с каждым модулем, который автоматизирует последовательность тестов. Это звучит как много работы, но поскольку Python такой лаконичный и гибкий, это на удивление легко. Можно сделать программирование гораздо более приятным и весёлым, написав тестовые функции параллельно с «производственным кодом», так как это позволяет легко находить ошибки и даже проектные недочёты на ранних этапах.165166«Вспомогательные модули», не предназначенные для роли главного модуля программы, могут включать самопроверку модуля.167168```python169if __name__ == "__main__":170 self_test()171```172173Даже программы, взаимодействующие со сложными внешними интерфейсами, могут быть протестированы в отсутствие этих интерфейсов с помощью «фиктивных» интерфейсов, реализованных на Python.174175### [Как создавать документацию из строк документации?](https://python-all.ru/3.1/faq/library.html#id12)176177Модуль [`pydoc`](https://python-all.ru/3.1/library/pydoc.html#module-pydoc) умеет создавать HTML из строк документации в исходном коде Python. Альтернатива для создания API-документации исключительно из docstrings – [epydoc](https://python-all.ru/3.1/faq/library.html). [Sphinx](https://python-all.ru/3.1/faq/library.html) также может включать содержимое docstring.178179### [Как получить нажатие одной клавиши за раз?](https://python-all.ru/3.1/faq/library.html#id13)180181Для вариантов Unix: есть несколько решений. Это легко сделать с помощью curses, но curses – довольно большой модуль для изучения.182183## [Потоки](https://python-all.ru/3.1/faq/library.html#id14)184185### [Как программировать с помощью потоков?](https://python-all.ru/3.1/faq/library.html#id15)186187Обязательно используйте модуль [`threading`](https://python-all.ru/3.1/library/threading.html#module-threading), а не модуль [`_thread`](https://python-all.ru/3.1/library/_thread.html#module-_thread). Модуль [`threading`](https://python-all.ru/3.1/library/threading.html#module-threading) предоставляет удобные абстракции поверх низкоуровневых примитивов, реализованных в модуле [`_thread`](https://python-all.ru/3.1/library/_thread.html#module-_thread).188189У Aahz есть набор слайдов из его руководства по многопоточности, которые могут быть полезны; см. [http://www.pythoncraft.com/OSCON2001/](https://python-all.ru/3.1/faq/library.html).190191### [Почему ни один из моих потоков не выполняется?](https://python-all.ru/3.1/faq/library.html#id16)192193Как только главный поток завершается, все потоки уничтожаются. Главный поток выполняется слишком быстро, не давая потокам времени на работу.194195Простое исправление – добавить в конец программы задержку, достаточно длинную для завершения всех потоков:196197```python198import threading, time199200def thread_task(name, n):201 for i in range(n): print(name, i)202203for i in range(10):204 T = threading.Thread(target=thread_task, args=(str(i), i))205 T.start()206207time.sleep(10) # <---------------------------!208```209210Но теперь (на многих платформах) потоки не выполняются параллельно, а, похоже, выполняются последовательно, один за другим! Причина в том, что планировщик потоков ОС не запускает новый поток, пока предыдущий не заблокирован.211212Простое исправление – добавить небольшую задержку в начало функции run:213214```python215def thread_task(name, n):216 time.sleep(0.001) # <--------------------!217 for i in range(n): print(name, i)218219for i in range(10):220 T = threading.Thread(target=thread_task, args=(str(i), i))221 T.start()222223time.sleep(10)224```225226Вместо того чтобы пытаться угадать, сколько времени займёт задержка [`time.sleep()`](https://python-all.ru/3.1/library/time.html#time.sleep), лучше использовать какой-нибудь механизм семафора. Одна из идей – использовать модуль [`queue`](https://python-all.ru/3.1/library/queue.html#module-queue) для создания объекта очереди, позволить каждому потоку добавлять токен в очередь по завершении, и позволить главному потоку читать из очереди столько токенов, сколько есть потоков.227228### [Как распределить работу между несколькими рабочими потоками?](https://python-all.ru/3.1/faq/library.html#id17)229230Используйте модуль [`queue`](https://python-all.ru/3.1/library/queue.html#module-queue) для создания очереди, содержащей список заданий. Класс [`Queue`](https://python-all.ru/3.1/library/queue.html#queue.Queue) поддерживает список объектов с `.put(obj)` для добавления элемента в очередь и `.get()` для получения элемента. Класс позаботится о блокировках, необходимых для гарантии того, что каждое задание будет выдано ровно один раз.231232Вот простой пример:233234```python235import threading, queue, time236237# Рабочий поток забирает задания из очереди. Когда очередь пуста, он238# предполагает, что больше работы не будет, и завершается.239# (На практике рабочие потоки работают до принудительного завершения.)240def worker ():241 print('Running worker')242 time.sleep(0.1)243 while True:244 try:245 arg = q.get(block=False)246 except queue.Empty:247 print('Worker', threading.currentThread(), end=' ')248 print('queue empty')249 break250 else:251 print('Worker', threading.currentThread(), end=' ')252 print('running with argument', arg)253 time.sleep(0.5)254255# Создать очередь256q = queue.Queue()257258# Запустить пул из 5 рабочих потоков259for i in range(5):260 t = threading.Thread(target=worker, name='worker %i' % (i+1))261 t.start()262263# Начать добавление заданий в очередь264for i in range(50):265 q.put(i)266267# Дать потокам время на выполнение268print('Main thread sleeping')269time.sleep(5)270```271272При запуске это выдаст следующий вывод:273274```python275Running worker276Running worker277Running worker278Running worker279Running worker280Main thread sleeping281Worker <Thread(worker 1, started 130283832797456)> running with argument 0282Worker <Thread(worker 2, started 130283824404752)> running with argument 1283Worker <Thread(worker 3, started 130283816012048)> running with argument 2284Worker <Thread(worker 4, started 130283807619344)> running with argument 3285Worker <Thread(worker 5, started 130283799226640)> running with argument 4286Worker <Thread(worker 1, started 130283832797456)> running with argument 5287...288```289290Обратитесь к документации модуля за подробностями; класс `Queue` предоставляет функциональный интерфейс.291292### [Какие виды изменения глобальных значений потокобезопасны?](https://python-all.ru/3.1/faq/library.html#id18)293294Глобальная блокировка интерпретатора (GIL) используется внутри для обеспечения того, что только один поток выполняется в виртуальной машине Python в любой момент времени. В целом, Python предлагает переключение между потоками только между инструкциями байт-кода; как часто происходит переключение, можно задать с помощью `sys.setswitchinterval()`. Каждая инструкция байт-кода и, следовательно, весь код реализации на C, достижимый из каждой инструкции, является атомарным с точки зрения программы на Python.295296В теории это означает, что точный учёт требует точного понимания реализации байт-кода PVM. На практике это означает, что операции над общими переменными встроенных типов данных (int, list, dict и т.д.), которые «выглядят атомарными», действительно являются таковыми.297298Например, следующие операции атомарны (L, L1, L2 – списки, D, D1, D2 – словари, x, y – объекты, i, j – целые числа):299300```python301L.append(x)302L1.extend(L2)303x = L[i]304x = L.pop()305L1[i:j] = L2306L.sort()307x = y308x.field = y309D[x] = y310D1.update(D2)311D.keys()312```313314А эти – нет:315316```python317i = i+1318L.append(L[-1])319L[i] = L[j]320D[x] = D[x] + 1321```322323Операции, замещающие другие объекты, могут вызвать метод [`__del__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__del__) этих объектов, когда их счётчик ссылок достигает нуля, и это может повлиять на выполнение. Особенно это касается массовых обновлений словарей и списков. В сомнительных случаях используйте мьютекс!324325### [Нельзя ли избавиться от глобальной блокировки интерпретатора?](https://python-all.ru/3.1/faq/library.html#id19)326327Глобальная блокировка интерпретатора (GIL) часто рассматривается как препятствие для развёртывания Python на высокопроизводительных многопроцессорных серверных машинах, поскольку многопоточная программа на Python эффективно использует только один CPU из-за требования, что (почти) весь код на Python может выполняться только пока удерживается GIL.328329Во времена Python 1.5 Грег Штайн (Greg Stein) реализовал обширный набор патчей (патчи «free threading»), который удалял GIL и заменял его мелкозернистой блокировкой. К сожалению, даже в Windows (где блокировки очень эффективны) это приводило к тому, что обычный код на Python работал примерно вдвое медленнее, чем интерпретатор с GIL. В Linux падение производительности было ещё больше, потому что блокировки pthread не так эффективны.330331С тех пор идея избавления от GIL периодически всплывала, но никто не нашёл способа справиться с ожидаемым замедлением, и пользователи, которые не используют потоки, не были бы рады, если бы их код работал вдвое медленнее. Набор патчей «free threading» Грега не обновлялся для более поздних версий Python.332333Это не значит, что вы не можете эффективно использовать Python на многоядерных машинах! Просто нужно творчески подойти к разделению работы между несколькими *процессами*, а не несколькими *потоками*. Разумное использование расширений на C также поможет; если использовать расширение C для выполнения длительной задачи, расширение может освободить GIL, пока поток выполнения находится в C-коде, и позволить другим потокам выполнить некоторую работу.334335Высказывались предложения сделать GIL блокировкой на уровне состояния интерпретатора, а не глобальной; тогда интерпретаторы не смогли бы обмениваться объектами. К сожалению, это тоже вряд ли произойдёт. Это потребовало бы огромного объёма работы, поскольку многие реализации объектов в настоящее время используют глобальное состояние. Например, небольшие целые числа и короткие строки кэшируются; эти кэши пришлось бы перенести в состояние интерпретатора. Другие типы объектов имеют свои собственные списки свободной памяти; эти списки также пришлось бы перенести. И так далее.336337И я сомневаюсь, что это вообще можно сделать за конечное время, потому что та же проблема существует и для сторонних расширений. Скорее всего, сторонние расширения пишутся быстрее, чем вы успеваете переделывать их для хранения всего глобального состояния в состоянии интерпретатора.338339И наконец, если у вас есть несколько интерпретаторов, не разделяющих состояние, что вы выигрываете по сравнению с запуском каждого интерпретатора в отдельном процессе?340341## [Ввод и вывод](https://python-all.ru/3.1/faq/library.html#id20)342343### [Как удалить файл? (И другие вопросы о файлах...)](https://python-all.ru/3.1/faq/library.html#id21)344345Используйте `os.remove(filename)` или `os.unlink(filename)`; документацию см. в модуле [`os`](https://python-all.ru/3.1/library/os.html#module-os). Эти две функции идентичны; [`unlink()`](https://python-all.ru/3.1/library/os.html#os.unlink) – это просто имя системного вызова Unix для данной функции.346347Для удаления каталога используйте [`os.rmdir()`](https://python-all.ru/3.1/library/os.html#os.rmdir); чтобы создать каталог – [`os.mkdir()`](https://python-all.ru/3.1/library/os.html#os.mkdir). `os.makedirs(path)` создаст все промежуточные каталоги в `path`, которые отсутствуют. `os.removedirs(path)` удалит промежуточные каталоги, если они пусты; если нужно удалить всё дерево каталогов вместе с содержимым, используйте [`shutil.rmtree()`](https://python-all.ru/3.1/library/shutil.html#shutil.rmtree).348349Для переименования файла используйте `os.rename(old_path, new_path)`.350351Чтобы обрезать файл, откройте его с помощью `f = open(filename, "rb+")`, и используйте `f.truncate(offset)`; параметр offset по умолчанию равен текущей позиции. Есть также `os.ftruncate(fd, offset)` для файлов, открытых с помощью [`os.open()`](https://python-all.ru/3.1/library/os.html#os.open), где `fd` – это файловый дескриптор (небольшое целое число).352353Модуль [`shutil`](https://python-all.ru/3.1/library/shutil.html#module-shutil) также содержит ряд функций для работы с файлами, включая [`copyfile()`](https://python-all.ru/3.1/library/shutil.html#shutil.copyfile), [`copytree()`](https://python-all.ru/3.1/library/shutil.html#shutil.copytree) и [`rmtree()`](https://python-all.ru/3.1/library/shutil.html#shutil.rmtree).354355### [Как скопировать файл?](https://python-all.ru/3.1/faq/library.html#id22)356357Модуль [`shutil`](https://python-all.ru/3.1/library/shutil.html#module-shutil) содержит функцию [`copyfile()`](https://python-all.ru/3.1/library/shutil.html#shutil.copyfile). Обратите внимание: в MacOS 9 она не копирует ветвь ресурсов (resource fork) и информацию Finder.358359### [Как читать (или записывать) двоичные данные?](https://python-all.ru/3.1/faq/library.html#id23)360361Для чтения и записи сложных двоичных форматов данных лучше всего использовать модуль [`struct`](https://python-all.ru/3.1/library/struct.html#module-struct). Он позволяет взять строку, содержащую двоичные данные (обычно числа), и преобразовать её в объекты Python; и наоборот.362363Например, следующий код читает из файла два 2-байтовых целых числа и одно 4-байтовое целое число в формате big-endian:364365```python366import struct367368with open(filename, "rb") as f:369 s = f.read(8)370 x, y, z = struct.unpack(">hhl", s)371```372373Символ ‘\>’ в строке формата указывает на порядок байтов big-endian; буква ‘h’ читает одно «короткое целое» (2 байта), а ‘l’ – одно «длинное целое» (4 байта) из строки.374375Для более регулярных данных (например, однородного списка целых чисел или чисел с плавающей запятой) можно также использовать модуль [`array`](https://python-all.ru/3.1/library/array.html#module-array).376377> > **Примечание**378> >379> > Для чтения и записи двоичных данных файл необходимо открывать в двоичном режиме (в данном случае передавая `"rb"` в [`open()`](https://python-all.ru/3.1/library/functions.html#open)). Если вместо этого использовать `"r"` (режим по умолчанию), файл откроется в текстовом режиме, и `f.read()` будет возвращать объекты [`str`](https://python-all.ru/3.1/library/functions.html#str), а не [`bytes`](https://python-all.ru/3.1/library/functions.html#bytes).380381### [Не удаётся использовать os.read() для канала, созданного с помощью os.popen(); почему?](https://python-all.ru/3.1/faq/library.html#id24)382383[`os.read()`](https://python-all.ru/3.1/library/os.html#os.read) – это низкоуровневая функция, которая принимает файловый дескриптор – небольшое целое число, представляющее открытый файл. `os.popen()` создаёт высокоуровневый файловый объект того же типа, что возвращается встроенной функцией [`open()`](https://python-all.ru/3.1/library/functions.html#open). Таким образом, чтобы прочитать n байт из канала p, созданного с помощью `os.popen()`, нужно использовать `p.read(n)`.384385### [Как получить доступ к последовательному порту (RS232)?](https://python-all.ru/3.1/faq/library.html#id25)386387Для Win32, POSIX (Linux, BSD и т. д.), Jython:388389> [http://pyserial.sourceforge.net](https://python-all.ru/3.1/faq/library.html)390391Для Unix смотрите сообщение в Usenet от Митча Чепмена:392393> [http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com](https://python-all.ru/3.1/faq/library.html)394395### [Почему закрытие sys.stdout (stdin, stderr) на самом деле не закрывает его?](https://python-all.ru/3.1/faq/library.html#id26)396397Python [*file objects*](https://python-all.ru/3.1/glossary.html#term-file-object) are a high-level layer of abstraction on low-level C file descriptors.398399Для большинства файловых объектов, создаваемых в Python с помощью встроенной функции [`open()`](https://python-all.ru/3.1/library/functions.html#open), вызов `f.close()` помечает файловый объект Python как закрытый с точки зрения Python, а также обеспечивает закрытие нижележащего дескриптора файла C. Это также происходит автоматически в деструкторе `f`, когда `f` становится мусором.400401Но stdin, stdout и stderr обрабатываются Python особым образом из-за особого статуса, который им присваивается в C. Вызов `sys.stdout.close()` помечает файловый объект на уровне Python как закрытый, но *не* закрывает соответствующий дескриптор файла C.402403Чтобы закрыть нижележащий дескриптор файла C для одного из этих трёх, сначала следует убедиться, что это действительно нужно сделать (например, это может запутать модули расширения, пытающиеся выполнять ввод-вывод). Если это так, следует использовать [`os.close()`](https://python-all.ru/3.1/library/os.html#os.close):404405```python406os.close(stdin.fileno())407os.close(stdout.fileno())408os.close(stderr.fileno())409```410411Или можно использовать числовые константы 0, 1 и 2 соответственно.412413## [Сетевое и интернет-программирование](https://python-all.ru/3.1/faq/library.html#id27)414415### [Какие WWW-инструменты есть для Python?](https://python-all.ru/3.1/faq/library.html#id28)416417Смотрите главы [*Интернет-протоколы и поддержка*](https://python-all.ru/3.1/library/internet.html#internet) и [*Обработка интернет-данных*](https://python-all.ru/3.1/library/netdata.html#netdata) в Справочном руководстве по библиотеке Python. В Python есть много модулей, которые помогут создать веб-системы как на стороне сервера, так и на стороне клиента.418419Сводка доступных фреймворков поддерживается Полом Бодди на [http://wiki.python.org/moin/WebProgramming](https://python-all.ru/3.1/faq/library.html).420421Кэмерон Лэрд поддерживает полезный набор страниц о веб-технологиях Python по адресу [http://phaseit.net/claird/comp.lang.python/web\_python](https://python-all.ru/3.1/faq/library.html).422423### [Как имитировать отправку CGI-формы (METHOD=POST)?](https://python-all.ru/3.1/faq/library.html#id29)424425Мне нужно получать веб-страницы, которые появляются после отправки формы. Существует ли готовый код, позволяющий это сделать?426427Да. Вот простой пример, использующий urllib.request:428429```python430#!/usr/local/bin/python431432import urllib.request433434### сформировать строку запроса435qs = "First=Josephine&MI=Q&Last=Public"436437### подключиться и отправить серверу путь438req = urllib.request.urlopen('http://www.some-server.out-there'439 '/cgi-bin/some-cgi-script', data=qs)440msg, hdrs = req.read(), req.info()441```442443Обратите внимание, что в целом для POST-операций с процентным кодированием строки запроса должны быть закодированы с помощью [`urllib.parse.urlencode()`](https://python-all.ru/3.1/library/urllib.parse.html#urllib.parse.urlencode). Например, чтобы отправить name="Guy Steele, Jr.":444445```python446>>> import urllib.parse447>>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'})448'name=Guy+Steele%2C+Jr.'449```450451> **См. также**452>453> [*Руководство по получению интернет-ресурсов с помощью пакета urllib*](https://python-all.ru/3.1/howto/urllib2.html#urllib-howto) с многочисленными примерами.454455### [Какой модуль использовать для генерации HTML?](https://python-all.ru/3.1/faq/library.html#id30)456457Доступно множество различных модулей:458459- HTMLgen – это библиотека классов объектов, соответствующих всем тегам разметки HTML 3.2. Она используется, когда вы пишете на Python и хотите синтезировать HTML-страницы для создания веб-сайта или для CGI-форм и т.д.460- DocumentTemplate и Zope Page Templates – это две разные системы, которые являются частью Zope.461- PTL от Quixote использует синтаксис Python для сборки строк текста.462463Дополнительные ссылки см. на [страницах вики по веб-программированию](https://python-all.ru/3.1/faq/library.html).464465### [Как отправить письмо из скрипта Python?](https://python-all.ru/3.1/faq/library.html#id31)466467Используйте модуль стандартной библиотеки [`smtplib`](https://python-all.ru/3.1/library/smtplib.html#module-smtplib).468469Вот очень простой интерактивный отправитель почты, использующий этот модуль. Этот метод будет\\nработать на любом хосте, поддерживающем SMTP-слушатель.470471```python472import sys, smtplib473474fromaddr = input("From: ")475toaddrs = input("To: ").split(',')476print("Enter message, end with ^D:")477msg = ''478while True:479 line = sys.stdin.readline()480 if not line:481 break482 msg += line483484# Непосредственная отправка письма485server = smtplib.SMTP('localhost')486server.sendmail(fromaddr, toaddrs, msg)487server.quit()488```489490A Unix-only alternative uses sendmail. The location of the sendmail program varies between systems; sometimes it is `/usr/lib/sendmail`, sometime `/usr/sbin/sendmail`. The sendmail manual page will help you out. Here’s some sample code:491492```python493SENDMAIL = "/usr/sbin/sendmail" # Расположение sendmail494import os495p = os.popen("%s -t -i" % SENDMAIL, "w")496p.write("To: receiver@example.com\n")497p.write("Subject: test\n")498p.write("\n") # Пустая строка, отделяющая заголовки от тела499p.write("Some text\n")500p.write("some more text\n")501sts = p.close()502if sts != 0:503 print("Sendmail exit status", sts)504```505506### [Как избежать блокировки в методе connect() сокета?](https://python-all.ru/3.1/faq/library.html#id32)507508Модуль select часто используется для организации асинхронного ввода-вывода через сокеты.509510Чтобы предотвратить блокировку при TCP-подключении, можно перевести сокет в неблокирующий режим. Затем при вызове `connect()` соединение либо установится сразу (маловероятно), либо будет получено исключение, содержащее номер ошибки в виде `.errno`. `⟦`errno.EINPROGRESS указывает, что соединение устанавливается, но ещё не завершено. Разные ОС возвращают разные значения, поэтому необходимо проверить, что возвращается в вашей системе.511512Можно использовать метод `connect_ex()`, чтобы избежать создания исключения. Он просто вернёт значение errno. Для опроса можно позже снова вызвать `connect_ex()` – `0` или `errno.EISCONN` указывают, что соединение установлено – или можно передать этот сокет в select, чтобы проверить, доступен ли он для записи.513514## [Базы данных](https://python-all.ru/3.1/faq/library.html#id33)515516### [Существуют ли интерфейсы к пакетам баз данных в Python?](https://python-all.ru/3.1/faq/library.html#id34)517518Да.519520Интерфейсы к дисковым хеш-таблицам, таким как [`DBM`](https://python-all.ru/3.1/library/dbm.html#module-dbm.ndbm) и [`GDBM`](https://python-all.ru/3.1/library/dbm.html#module-dbm.gnu), также включены в стандартную библиотеку Python. Также есть модуль [`sqlite3`](https://python-all.ru/3.1/library/sqlite3.html#module-sqlite3), который предоставляет лёгкую дисковую реляционную базу данных.521522Доступна поддержка большинства реляционных баз данных. Подробнее см. на [вики-странице DatabaseProgramming](https://python-all.ru/3.1/faq/library.html).523524### [Как реализовать постоянные объекты в Python?](https://python-all.ru/3.1/faq/library.html#id35)525526Модуль библиотеки [`pickle`](https://python-all.ru/3.1/library/pickle.html#module-pickle) решает эту проблему очень общим способом (хотя по-прежнему нельзя хранить такие вещи, как открытые файлы, сокеты или окна), а модуль библиотеки [`shelve`](https://python-all.ru/3.1/library/shelve.html#module-shelve) использует pickle и (g)dbm для создания постоянных отображений, содержащих произвольные объекты Python.527528Более неуклюжий способ – использовать младшую сестру pickle – модуль marshal. Модуль [`marshal`](https://python-all.ru/3.1/library/marshal.html#module-marshal) предоставляет очень быстрые способы сохранения нециклических базовых типов Python в файлы и строки и обратно. Хотя marshal не делает сложных вещей, таких как сохранение экземпляров или корректная обработка общих ссылок, он работает чрезвычайно быстро. Например, загрузка полмегабайта данных может занять менее трети секунды. Это часто оказывается быстрее, чем использовать что-то более сложное и универсальное, например gdbm с pickle/shelve.529530### [Если моя программа аварийно завершилась с открытой базой данных bsddb (или anydbm), она повреждается. Почему?](https://python-all.ru/3.1/faq/library.html#id36)531532> **Примечание**533>534> The bsddb module is now available as a standalone package [pybsddb](https://python-all.ru/3.1/faq/library.html).535536Databases opened for write access with the bsddb module (and often by the anydbm module, since it will preferentially use bsddb) must explicitly be closed using the `.close()` method of the database. The underlying library caches database contents which need to be converted to on-disk form and written.537538Если вы инициализировали новую базу данных bsddb, но ничего в неё не записали до сбоя программы, в результате часто остаётся файл нулевой длины, и при следующем открытии возникнет исключение.539540### [Я попытался открыть файл Berkeley DB, но bsddb выдаёт bsddb.error: (22, ‘Invalid argument’). Помогите! Как восстановить мои данные?](https://python-all.ru/3.1/faq/library.html#id37)541542> **Примечание**543>544> Модуль bsddb теперь доступен как отдельный пакет [pybsddb](https://python-all.ru/3.1/faq/library.html).545546Не паникуйте! Ваши данные, скорее всего, целы. Самая частая причина ошибки – попытка открыть более старый файл Berkeley DB с более новой версией библиотеки Berkeley DB.547548Во многих системах Linux теперь доступны все три версии Berkeley DB. Если вы переходите с версии 1 на более новую, используйте db\_dump185 для создания текстового дампа базы данных. Если вы переходите с версии 2 на версию 3, используйте db2\_dump для создания текстовой версии базы данных. В любом случае используйте db\_load для создания новой родной базы данных для последней версии, установленной на вашем компьютере. Если у вас установлена версия 3 Berkeley DB, вы сможете использовать db2\_load для создания родной базы данных версии 2.549550Следует отказаться от файлов Berkeley DB версии 1, поскольку код хэш-файлов содержит известные ошибки, которые могут повредить ваши данные.551552## [Математика и численные методы](https://python-all.ru/3.1/faq/library.html#id38)553554### [Как генерировать случайные числа в Python?](https://python-all.ru/3.1/faq/library.html#id39)555556Стандартный модуль [`random`](https://python-all.ru/3.1/library/random.html#module-random) реализует генератор случайных чисел. Использование простое:557558```python559import random560random.random()561```562563Возвращает случайное число с плавающей запятой в диапазоне \[0, 1).564565В этом модуле также есть много других специализированных генераторов, например:566567- `randrange(a, b)` выбирает целое число в диапазоне \[a, b).568- `uniform(a, b)` выбирает число с плавающей точкой в диапазоне \[a, b).569- `normalvariate(mean, sdev)` возвращает случайное число из нормального (гауссова) распределения.570571Некоторые функции более высокого уровня работают непосредственно с последовательностями, например:572573- `choice(S)` выбирает случайный элемент из заданной последовательности574- `shuffle(L)` перемешивает список на месте, т.е. переставляет его элементы случайным образом575576Также существует класс `Random`, который можно инстанцировать для создания нескольких независимых генераторов случайных чисел.577