Документация Python неофициальный перевод

library.md

650 строк · 62.3 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.6/faq/library.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [Часто задаваемые вопросы по библиотекам и расширениям](https://python-all.ru/2.6/faq/library.html#id1)89Содержание1011- [FAQ по библиотекам и расширениям](https://python-all.ru/2.6/faq/library.html#library-and-extension-faq)1213  - [Общие вопросы по библиотекам](https://python-all.ru/2.6/faq/library.html#general-library-questions)1415    - [Как найти модуль или приложение для выполнения задачи X?](https://python-all.ru/2.6/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/2.6/faq/library.html#where-is-the-math-py-socket-py-regex-py-etc-source-file)17    - [Как сделать скрипт Python исполняемым в Unix?](https://python-all.ru/2.6/faq/library.html#how-do-i-make-a-python-script-executable-on-unix)18    - [Существует ли пакет curses/termcap для Python?](https://python-all.ru/2.6/faq/library.html#is-there-a-curses-termcap-package-for-python)19    - [Есть ли в Python эквивалент onexit() из C?](https://python-all.ru/2.6/faq/library.html#is-there-an-equivalent-to-c-s-onexit-in-python)20    - [Почему не работают мои обработчики сигналов?](https://python-all.ru/2.6/faq/library.html#why-don-t-my-signal-handlers-work)21  - [Типовые задачи](https://python-all.ru/2.6/faq/library.html#common-tasks)2223    - [Как протестировать программу или компонент Python?](https://python-all.ru/2.6/faq/library.html#how-do-i-test-a-python-program-or-component)24    - [Как создать документацию из строк документации?](https://python-all.ru/2.6/faq/library.html#how-do-i-create-documentation-from-doc-strings)25    - [Как получить одиночное нажатие клавиши?](https://python-all.ru/2.6/faq/library.html#how-do-i-get-a-single-keypress-at-a-time)26  - [Потоки](https://python-all.ru/2.6/faq/library.html#threads)2728    - [Как программировать с использованием потоков?](https://python-all.ru/2.6/faq/library.html#how-do-i-program-using-threads)29    - [Ни один из моих потоков не запускается: почему?](https://python-all.ru/2.6/faq/library.html#none-of-my-threads-seem-to-run-why)30    - [Как распределить работу между несколькими рабочими потоками?](https://python-all.ru/2.6/faq/library.html#how-do-i-parcel-out-work-among-a-bunch-of-worker-threads)31    - [Какие виды изменения глобальных значений являются потокобезопасными?](https://python-all.ru/2.6/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe)32    - [Нельзя ли избавиться от глобальной блокировки интерпретатора (GIL)?](https://python-all.ru/2.6/faq/library.html#can-t-we-get-rid-of-the-global-interpreter-lock)33  - [Ввод и вывод](https://python-all.ru/2.6/faq/library.html#input-and-output)3435    - [Как удалить файл? (И другие вопросы о файлах...)](https://python-all.ru/2.6/faq/library.html#how-do-i-delete-a-file-and-other-file-questions)36    - [Как скопировать файл?](https://python-all.ru/2.6/faq/library.html#how-do-i-copy-a-file)37    - [Как читать (или записывать) двоичные данные?](https://python-all.ru/2.6/faq/library.html#how-do-i-read-or-write-binary-data)38    - [Не удаётся использовать os.read() на канале, созданном с помощью os.popen(); почему?](https://python-all.ru/2.6/faq/library.html#i-can-t-seem-to-use-os-read-on-a-pipe-created-with-os-popen-why)39    - [Как запустить подпроцесс с каналами, подключёнными и ко входу, и к выходу?](https://python-all.ru/2.6/faq/library.html#how-do-i-run-a-subprocess-with-pipes-connected-to-both-input-and-output)40    - [Как получить доступ к последовательному порту (RS232)?](https://python-all.ru/2.6/faq/library.html#how-do-i-access-the-serial-rs232-port)41    - [Почему закрытие sys.stdout (stdin, stderr) на самом деле не закрывает его?](https://python-all.ru/2.6/faq/library.html#why-doesn-t-closing-sys-stdout-stdin-stderr-really-close-it)42  - [Сетевое и интернет-программирование](https://python-all.ru/2.6/faq/library.html#network-internet-programming)4344    - [Какие существуют инструменты для работы с WWW в Python?](https://python-all.ru/2.6/faq/library.html#what-www-tools-are-there-for-python)45    - [Как имитировать отправку CGI-формы (METHOD=POST)?](https://python-all.ru/2.6/faq/library.html#how-can-i-mimic-cgi-form-submission-method-post)46    - [Какой модуль использовать для генерации HTML?](https://python-all.ru/2.6/faq/library.html#what-module-should-i-use-to-help-with-generating-html)47    - [Как отправить письмо из скрипта Python?](https://python-all.ru/2.6/faq/library.html#how-do-i-send-mail-from-a-python-script)48    - [Как избежать блокировки в методе connect() сокета?](https://python-all.ru/2.6/faq/library.html#how-do-i-avoid-blocking-in-the-connect-method-of-a-socket)49  - [Базы данных](https://python-all.ru/2.6/faq/library.html#databases)5051    - [Существуют ли интерфейсы к пакетам баз данных в Python?](https://python-all.ru/2.6/faq/library.html#are-there-any-interfaces-to-database-packages-in-python)52    - [Как реализовать постоянные объекты в Python?](https://python-all.ru/2.6/faq/library.html#how-do-you-implement-persistent-objects-in-python)53    - [Почему cPickle такой медленный?](https://python-all.ru/2.6/faq/library.html#why-is-cpickle-so-slow)54    - [Если моя программа аварийно завершается с открытой базой данных bsddb (или anydbm), она повреждается. Почему?](https://python-all.ru/2.6/faq/library.html#if-my-program-crashes-with-a-bsddb-or-anydbm-database-open-it-gets-corrupted-how-come)55    - [Я попытался открыть файл Berkeley DB, но bsddb выдаёт bsddb.error: (22, 'Invalid argument'). Помогите! Как восстановить данные?](https://python-all.ru/2.6/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)56  - [Математика и численные методы](https://python-all.ru/2.6/faq/library.html#mathematics-and-numerics)5758    - [Как генерировать случайные числа в Python?](https://python-all.ru/2.6/faq/library.html#how-do-i-generate-random-numbers-in-python)5960## [Общие вопросы по библиотекам](https://python-all.ru/2.6/faq/library.html#id2)6162### [Как найти модуль или приложение для выполнения задачи X?](https://python-all.ru/2.6/faq/library.html#id3)6364Проверьте [*Справочник по библиотеке*](https://python-all.ru/2.6/library/index.html#library-index), чтобы узнать, есть ли подходящий модуль в стандартной библиотеке. (Со временем вы выучите, что есть в стандартной библиотеке, и сможете пропустить этот шаг.)6566Для сторонних пакетов выполните поиск в [Python Package Index](https://python-all.ru/2.6/faq/library.html) или воспользуйтесь [Google](https://python-all.ru/2.6/faq/library.html) или другой поисковой системой. Обычно поиск по «Python» с одним-двумя ключевыми словами по вашей теме находит что-нибудь полезное.6768### [Где находится исходный файл math.py (socket.py, regex.py и т. д.)?](https://python-all.ru/2.6/faq/library.html#id4)6970Если не удаётся найти исходный файл для модуля, возможно, он является встроенным или динамически загружаемым модулем, реализованным на C, C++ или другом компилируемом языке. В таком случае исходный файл может отсутствовать или находиться, например, в файле mathmodule.c где-то в каталоге исходных текстов на C (не в Python Path).7172В Python существует (как минимум) три вида модулей:73741. модули, написанные на Python (.py);752. модули, написанные на C и динамически загружаемые (.dll, .pyd, .so, .sl и т. д.);763. модули, написанные на C и связанные с интерпретатором; чтобы получить их список, введите:7778   ```python79   import sys80   print sys.builtin_module_names81   ```8283### [Как сделать скрипт Python исполняемым в Unix?](https://python-all.ru/2.6/faq/library.html#id5)8485Нужно сделать две вещи: установить исполняемый режим для файла скрипта и убедиться, что первая строка начинается с `#!`, за которым следует путь к интерпретатору Python.8687Первый способ: выполнить `chmod +x scriptfile` или, возможно, `chmod 755 scriptfile`.8889Второе можно сделать несколькими способами. Самый простой – написать9091```python92#!/usr/local/bin/python93```9495в самой первой строке файла, указав путь к установленному на вашей платформе интерпретатору Python.9697Если вы хотите, чтобы скрипт не зависел от расположения интерпретатора Python, вы можете использовать программу «env». Почти все варианты Unix поддерживают следующее, при условии, что интерпретатор Python находится в каталоге, указанном в переменной $PATH пользователя:9899```python100#!/usr/bin/env python101```102103*Не* делайте этого для CGI-скриптов. Переменная $PATH для CGI-скриптов часто очень мала, поэтому необходимо использовать фактический абсолютный путь к интерпретатору.104105Иногда окружение пользователя настолько заполнено, что программа /usr/bin/env не срабатывает; или программы env вообще нет. В этом случае можно попробовать следующий трюк (от Алекса Резински):106107```python108#! /bin/sh109""":"110exec python $0 ${1+"$@"}111"""112```113114Небольшой недостаток в том, что при этом определяется строка документации \_\_doc\_\_ скрипта. Однако это можно исправить, добавив115116```python117__doc__ = """...Whatever..."""118```119120### [Существует ли пакет curses/termcap для Python?](https://python-all.ru/2.6/faq/library.html#id6)121122Для вариантов Unix: стандартный дистрибутив исходных текстов Python поставляется с модулем curses в подкаталоге `Modules/`, хотя по умолчанию он не компилируется (обратите внимание, что он недоступен в дистрибутиве Windows – модуля curses для Windows не существует).123124Модуль curses поддерживает базовые возможности curses, а также многие дополнительные функции из ncurses и SYSV curses, такие как цвет, поддержка альтернативных наборов символов, pad'ы и поддержка мыши. Это означает, что модуль несовместим с операционными системами, имеющими только BSD curses, но в настоящее время, похоже, нет поддерживаемых ОС, попадающих в эту категорию.125126Для Windows: используйте [модуль consolelib](https://python-all.ru/2.6/faq/library.html).127128### [Есть ли в Python аналог onexit() из C?](https://python-all.ru/2.6/faq/library.html#id7)129130Модуль [`atexit`](https://python-all.ru/2.6/library/atexit.html#module-atexit) предоставляет функцию register, аналогичную C'овской onexit.131132### [Почему не работают мои обработчики сигналов?](https://python-all.ru/2.6/faq/library.html#id8)133134Самая распространённая проблема – обработчик сигнала объявлен с неправильным списком аргументов. Он вызывается как135136```python137handler(signum, frame)138```139140поэтому он должен быть объявлен с двумя аргументами:141142```python143def handler(signum, frame):144    ...145```146147## [Типовые задачи](https://python-all.ru/2.6/faq/library.html#id9)148149### [Как тестировать программу или компонент Python?](https://python-all.ru/2.6/faq/library.html#id10)150151В состав Python входят два фреймворка для тестирования. Модуль [`doctest`](https://python-all.ru/2.6/library/doctest.html#module-doctest) находит примеры в строках документации модуля и запускает их, сравнивая вывод с ожидаемым результатом, указанным в docstring.152153Модуль [`unittest`](https://python-all.ru/2.6/library/unittest.html#module-unittest) – это более продвинутый фреймворк для тестирования, созданный по образцу фреймворков Java и Smalltalk.154155Для тестирования полезно писать программу так, чтобы её можно было легко тестировать с помощью хорошего модульного дизайна. Программа должна почти всю функциональность инкапсулировать в функции или методы классов – и это иногда имеет удивительный и приятный эффект: программа работает быстрее (потому что доступ к локальным переменным быстрее, чем к глобальным). Кроме того, программа должна избегать зависимости от изменения глобальных переменных, так как это делает тестирование гораздо более сложным.156157«Глобальная основная логика» вашей программы может быть такой же простой, как158159```python160if __name__ == "__main__":161    main_logic()162```163164в конце главного модуля программы.165166Как только ваша программа организована как управляемая совокупность функций и поведений классов, следует написать тестовые функции, которые проверяют эти поведения. Набор тестов можно связать с каждым модулем, который автоматизирует последовательность тестов. Это звучит как много работы, но поскольку Python такой лаконичный и гибкий, это на удивление легко. Можно сделать программирование гораздо более приятным и весёлым, написав тестовые функции параллельно с «производственным кодом», так как это позволяет легко находить ошибки и даже проектные недочёты на ранних этапах.167168«Вспомогательные модули», не предназначенные для роли главного модуля программы, могут включать самопроверку модуля.169170```python171if __name__ == "__main__":172    self_test()173```174175Даже программы, взаимодействующие со сложными внешними интерфейсами, могут быть протестированы в отсутствие этих интерфейсов с помощью «фиктивных» интерфейсов, реализованных на Python.176177### [Как создавать документацию из строк документации?](https://python-all.ru/2.6/faq/library.html#id11)178179Модуль [`pydoc`](https://python-all.ru/2.6/library/pydoc.html#module-pydoc) умеет создавать HTML из строк документации в исходном коде Python. Альтернатива для создания API-документации исключительно из docstrings – [epydoc](https://python-all.ru/2.6/faq/library.html). [Sphinx](https://python-all.ru/2.6/faq/library.html) также может включать содержимое docstring.180181### [Как получить нажатие одной клавиши за раз?](https://python-all.ru/2.6/faq/library.html#id12)182183Для вариантов Unix: есть несколько решений. Это легко сделать с помощью curses, но curses – довольно большой модуль для изучения. Вот решение без curses:184185```python186import termios, fcntl, sys, os187fd = sys.stdin.fileno()188189oldterm = termios.tcgetattr(fd)190newattr = termios.tcgetattr(fd)191newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO192termios.tcsetattr(fd, termios.TCSANOW, newattr)193194oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)195fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)196197try:198    while 1:199        try:200            c = sys.stdin.read(1)201            print "Got character", repr(c)202        except IOError: pass203finally:204    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)205    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)206```207208Для всего этого нужны модули [`termios`](https://python-all.ru/2.6/library/termios.html#module-termios) и [`fcntl`](https://python-all.ru/2.6/library/fcntl.html#module-fcntl); я пробовал это только в Linux, но должно работать и в других системах. В этом коде символы читаются и выводятся по одному.209210[`termios.tcsetattr()`](https://python-all.ru/2.6/library/termios.html#termios.tcsetattr) отключает эхо-вывод stdin и отключает канонический режим. `fcntl.fcntl()` используется для получения флагов файлового дескриптора stdin и их изменения для неблокирующего режима. Поскольку чтение из пустого stdin приводит к [`IOError`](https://python-all.ru/2.6/library/exceptions.html#exceptions.IOError), это исключение перехватывается и игнорируется.211212## [Потоки](https://python-all.ru/2.6/faq/library.html#id13)213214### [Как программировать с помощью потоков?](https://python-all.ru/2.6/faq/library.html#id14)215216Be sure to use the [`threading`](https://python-all.ru/2.6/library/threading.html#module-threading) module and not the [`thread`](https://python-all.ru/2.6/library/thread.html#module-thread) module. The [`threading`](https://python-all.ru/2.6/library/threading.html#module-threading) module builds convenient abstractions on top of the low-level primitives provided by the [`thread`](https://python-all.ru/2.6/library/thread.html#module-thread) module.217218У Aahz есть набор слайдов из его руководства по многопоточности, которые могут быть полезны; см. [http://www.pythoncraft.com/OSCON2001/](https://python-all.ru/2.6/faq/library.html).219220### [Почему ни один из моих потоков не выполняется?](https://python-all.ru/2.6/faq/library.html#id15)221222Как только главный поток завершается, все потоки уничтожаются. Главный поток выполняется слишком быстро, не давая потокам времени на работу.223224Простое исправление – добавить в конец программы задержку, достаточно длинную для завершения всех потоков:225226```python227import threading, time228229def thread_task(name, n):230    for i in range(n): print name, i231232for i in range(10):233    T = threading.Thread(target=thread_task, args=(str(i), i))234    T.start()235236time.sleep(10) # <----------------------------!237```238239Но теперь (на многих платформах) потоки не выполняются параллельно, а, похоже, выполняются последовательно, один за другим! Причина в том, что планировщик потоков ОС не запускает новый поток, пока предыдущий не заблокирован.240241Простое исправление – добавить небольшую задержку в начало функции run:242243```python244def thread_task(name, n):245    time.sleep(0.001) # <---------------------!246    for i in range(n): print name, i247248for i in range(10):249    T = threading.Thread(target=thread_task, args=(str(i), i))250    T.start()251252time.sleep(10)253```254255Вместо того чтобы пытаться угадать, какой задержки [`time.sleep()`](https://python-all.ru/2.6/library/time.html#time.sleep) будет достаточно, лучше использовать какой-нибудь механизм семафора. Одна из идей – использовать модуль [`Queue`](https://python-all.ru/2.6/library/queue.html#module-Queue) для создания объекта очереди, позволить каждому потоку добавлять маркер в очередь по завершении, а главному потоку – читать из очереди столько маркеров, сколько потоков.256257### [Как распределить работу между несколькими рабочими потоками?](https://python-all.ru/2.6/faq/library.html#id16)258259Используйте модуль [`Queue`](https://python-all.ru/2.6/library/queue.html#module-Queue) для создания очереди, содержащей список задач. Класс [`Queue`](https://python-all.ru/2.6/library/queue.html#Queue.Queue) поддерживает список объектов с методами `.put(obj)` для добавления элемента в очередь и `.get()` для извлечения элемента. Класс сам позаботится о блокировках, необходимых для того, чтобы каждая задача была выдана ровно один раз.260261Вот простой пример:262263```python264import threading, Queue, time265266# Рабочий поток забирает задания из очереди. Когда очередь пуста, он267# предполагает, что больше работы не будет, и завершается.268# (На практике рабочие потоки работают до принудительного завершения.)269def worker ():270    print 'Running worker'271    time.sleep(0.1)272    while True:273        try:274            arg = q.get(block=False)275        except Queue.Empty:276            print 'Worker', threading.currentThread(),277            print 'queue empty'278            break279        else:280            print 'Worker', threading.currentThread(),281            print 'running with argument', arg282            time.sleep(0.5)283284# Создать очередь285q = Queue.Queue()286287# Запустить пул из 5 рабочих потоков288for i in range(5):289    t = threading.Thread(target=worker, name='worker %i' % (i+1))290    t.start()291292# Начать добавление заданий в очередь293for i in range(50):294    q.put(i)295296# Дать потокам время на выполнение297print 'Main thread sleeping'298time.sleep(5)299```300301При запуске это выдаст следующий вывод:302303> Рабочий поток запущен Рабочий поток запущен Рабочий поток запущен Рабочий поток запущен Рабочий поток запущен Главный поток спит Рабочий поток \<Thread(worker 1, started)\> выполняется с аргументом 0 Рабочий поток \<Thread(worker 2, started)\> выполняется с аргументом 1 Рабочий поток \<Thread(worker 3, started)\> выполняется с аргументом 2 Рабочий поток \<Thread(worker 4, started)\> выполняется с аргументом 3 Рабочий поток \<Thread(worker 5, started)\> выполняется с аргументом 4 Рабочий поток \<Thread(worker 1, started)\> выполняется с аргументом 5 ...304305Обратитесь к документации модуля за подробностями; класс `Queue` предоставляет функциональный интерфейс.306307### [Какие виды изменения глобальных значений потокобезопасны?](https://python-all.ru/2.6/faq/library.html#id17)308309Глобальная блокировка интерпретатора (GIL) используется внутренне, чтобы гарантировать, что в любой момент времени в виртуальной машине Python выполняется только один поток. В целом Python переключается между потоками только между инструкциями байт-кода; частота переключений задаётся через [`sys.setcheckinterval()`](https://python-all.ru/2.6/library/sys.html#sys.setcheckinterval). Каждая инструкция байт-кода и, следовательно, весь код реализации на C, достигаемый из каждой инструкции, является атомарным с точки зрения программы Python.310311Теоретически это означает, что точный учёт требует точного понимания реализации байткода виртуальной машины Python. На практике это означает, что операции над совместно используемыми переменными встроенных типов (int, list, dict и т.д.), которые «выглядят атомарными», действительно атомарны.312313Например, следующие операции атомарны (L, L1, L2 – списки, D, D1, D2 – словари, x, y – объекты, i, j – целые числа):314315```python316L.append(x)317L1.extend(L2)318x = L[i]319x = L.pop()320L1[i:j] = L2321L.sort()322x = y323x.field = y324D[x] = y325D1.update(D2)326D.keys()327```328329А эти – нет:330331```python332i = i+1333L.append(L[-1])334L[i] = L[j]335D[x] = D[x] + 1336```337338Операции, замещающие другие объекты, могут вызвать метод [`__del__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__del__) этих объектов, когда их счётчик ссылок достигает нуля, и это может повлиять на выполнение. Особенно это касается массовых обновлений словарей и списков. В сомнительных случаях используйте мьютекс!339340### [Нельзя ли избавиться от глобальной блокировки интерпретатора?](https://python-all.ru/2.6/faq/library.html#id18)341342Глобальная блокировка интерпретатора (GIL) часто рассматривается как препятствие для развёртывания Python на высокопроизводительных многопроцессорных серверных машинах, поскольку многопоточная программа на Python эффективно использует только один CPU из-за требования, что (почти) весь код на Python может выполняться только пока удерживается GIL.343344Во времена Python 1.5 Грег Штайн (Greg Stein) реализовал обширный набор патчей (патчи «free threading»), который удалял GIL и заменял его мелкозернистой блокировкой. К сожалению, даже в Windows (где блокировки очень эффективны) это приводило к тому, что обычный код на Python работал примерно вдвое медленнее, чем интерпретатор с GIL. В Linux падение производительности было ещё больше, потому что блокировки pthread не так эффективны.345346С тех пор идея избавления от GIL периодически всплывала, но никто не нашёл способа справиться с ожидаемым замедлением, и пользователи, которые не используют потоки, не были бы рады, если бы их код работал вдвое медленнее. Набор патчей «free threading» Грега не обновлялся для более поздних версий Python.347348Это не значит, что вы не можете эффективно использовать Python на многоядерных машинах! Просто нужно творчески подойти к разделению работы между несколькими *процессами*, а не несколькими *потоками*. Разумное использование расширений на C также поможет; если использовать расширение C для выполнения длительной задачи, расширение может освободить GIL, пока поток выполнения находится в C-коде, и позволить другим потокам выполнить некоторую работу.349350Высказывались предложения сделать GIL блокировкой на уровне состояния интерпретатора, а не глобальной; тогда интерпретаторы не смогли бы обмениваться объектами. К сожалению, это тоже вряд ли произойдёт. Это потребовало бы огромного объёма работы, поскольку многие реализации объектов в настоящее время используют глобальное состояние. Например, небольшие целые числа и короткие строки кэшируются; эти кэши пришлось бы перенести в состояние интерпретатора. Другие типы объектов имеют свои собственные списки свободной памяти; эти списки также пришлось бы перенести. И так далее.351352И я сомневаюсь, что это вообще можно сделать за конечное время, потому что та же проблема существует и для сторонних расширений. Скорее всего, сторонние расширения пишутся быстрее, чем вы успеваете переделывать их для хранения всего глобального состояния в состоянии интерпретатора.353354И наконец, если у вас есть несколько интерпретаторов, не разделяющих состояние, что вы выигрываете по сравнению с запуском каждого интерпретатора в отдельном процессе?355356## [Ввод и вывод](https://python-all.ru/2.6/faq/library.html#id19)357358### [Как удалить файл? (И другие вопросы о файлах...)](https://python-all.ru/2.6/faq/library.html#id20)359360Используйте `os.remove(filename)` или `os.unlink(filename)`; документацию см. в модуле [`os`](https://python-all.ru/2.6/library/os.html#module-os). Обе функции идентичны; `unlink()` – это просто имя системного вызова Unix для этой функции.361362Для удаления каталога используйте [`os.rmdir()`](https://python-all.ru/2.6/library/os.html#os.rmdir); чтобы создать каталог – [`os.mkdir()`](https://python-all.ru/2.6/library/os.html#os.mkdir). `os.makedirs(path)` создаст все промежуточные каталоги в `path`, которые отсутствуют. `os.removedirs(path)` удалит промежуточные каталоги, если они пусты; если нужно удалить всё дерево каталогов вместе с содержимым, используйте [`shutil.rmtree()`](https://python-all.ru/2.6/library/shutil.html#shutil.rmtree).363364Для переименования файла используйте `os.rename(old_path, new_path)`.365366Чтобы обрезать файл, откройте его с помощью `f = open(filename, "r+")` и используйте `f.truncate(offset)`; offset по умолчанию равен текущей позиции. Существует также `` `os.ftruncate(fd, offset) `` для файлов, открытых с помощью [`os.open()`](https://python-all.ru/2.6/library/os.html#os.open), где `fd` – это файловый дескриптор (небольшое целое число).367368Модуль [`shutil`](https://python-all.ru/2.6/library/shutil.html#module-shutil) также содержит ряд функций для работы с файлами, включая [`copyfile()`](https://python-all.ru/2.6/library/shutil.html#shutil.copyfile), [`copytree()`](https://python-all.ru/2.6/library/shutil.html#shutil.copytree) и [`rmtree()`](https://python-all.ru/2.6/library/shutil.html#shutil.rmtree).369370### [Как скопировать файл?](https://python-all.ru/2.6/faq/library.html#id21)371372Модуль [`shutil`](https://python-all.ru/2.6/library/shutil.html#module-shutil) содержит функцию [`copyfile()`](https://python-all.ru/2.6/library/shutil.html#shutil.copyfile). Обратите внимание: в MacOS 9 она не копирует ветвь ресурсов (resource fork) и информацию Finder.373374### [Как читать (или записывать) двоичные данные?](https://python-all.ru/2.6/faq/library.html#id22)375376Для чтения и записи сложных двоичных форматов данных лучше всего использовать модуль [`struct`](https://python-all.ru/2.6/library/struct.html#module-struct). Он позволяет взять строку, содержащую двоичные данные (обычно числа), и преобразовать её в объекты Python; и наоборот.377378Например, следующий код читает из файла два 2-байтовых целых числа и одно 4-байтовое целое число в формате big-endian:379380```python381import struct382383f = open(filename, "rb")  # Открыть в бинарном режиме для переносимости384s = f.read(8)385x, y, z = struct.unpack(">hhl", s)386```387388Символ ‘\>’ в строке формата указывает на порядок байтов big-endian; буква ‘h’ читает одно «короткое целое» (2 байта), а ‘l’ – одно «длинное целое» (4 байта) из строки.389390Для более регулярных данных (например, однородного списка целых чисел или чисел с плавающей запятой) можно также использовать модуль [`array`](https://python-all.ru/2.6/library/array.html#module-array).391392### [Не удаётся использовать os.read() для канала, созданного с помощью os.popen(); почему?](https://python-all.ru/2.6/faq/library.html#id23)393394[`os.read()`](https://python-all.ru/2.6/library/os.html#os.read) – это низкоуровневая функция, принимающая файловый дескриптор – небольшое целое число, представляющее открытый файл. [`os.popen()`](https://python-all.ru/2.6/library/os.html#os.popen) создает высокоуровневый файловый объект того же типа, что возвращает встроенная функция [`open()`](https://python-all.ru/2.6/library/functions.html#open). Таким образом, чтобы прочитать n байт из канала p, созданного с помощью [`os.popen()`](https://python-all.ru/2.6/library/os.html#os.popen), нужно использовать `p.read(n)`.395396### [Как запустить подпроцесс с каналами, подключёнными и ко входу, и к выходу?](https://python-all.ru/2.6/faq/library.html#id24)397398Используйте модуль [`popen2`](https://python-all.ru/2.6/library/popen2.html#module-popen2). Например:399400```python401import popen2402fromchild, tochild = popen2.popen2("command")403tochild.write("input\n")404tochild.flush()405output = fromchild.readline()406```407408Предупреждение: в целом делать это неразумно, поскольку можно легко вызвать взаимную блокировку (deadlock), при которой ваш процесс блокируется в ожидании вывода от дочернего процесса, а дочерний процесс блокируется в ожидании ввода от вас. Это может произойти, если родительский процесс ожидает от дочернего больше текста, чем тот выводит, или из-за данных, застрявших в буферах stdio из-за отсутствия сброса. Родительский процесс на Python может, конечно, явно сбросить данные, отправляемые дочернему процессу, перед чтением любого вывода, но если дочерний процесс – это простая программа на C, она может быть написана так, что никогда не сбрасывает свой вывод явно, даже если работает в интерактивном режиме, поскольку сброс обычно происходит автоматически.409410Обратите внимание, что взаимная блокировка возможна и при использовании `popen3()` для чтения stdout и stderr. Если один из двух потоков слишком велик для внутреннего буфера (увеличение размера буфера не помогает) и вы сначала читаете `read()` другой, также возникает взаимная блокировка.411412Примечание об ошибке в popen2: если ваша программа не вызывает `wait()` или `waitpid()`, завершённые дочерние процессы никогда не удаляются, и в конечном итоге вызовы popen2 будут завершаться ошибкой из-за ограничения на количество дочерних процессов. Вызов [`os.waitpid()`](https://python-all.ru/2.6/library/os.html#os.waitpid) с опцией [`os.WNOHANG`](https://python-all.ru/2.6/library/os.html#os.WNOHANG) может предотвратить это; хорошее место для такого вызова – перед повторным вызовом `popen2`.413414Во многих случаях всё, что нужно – это передать данные команде и получить результат. Если объём данных не очень велик, проще всего записать их во временный файл и запустить команду с этим файлом в качестве ввода. Стандартный модуль [`tempfile`](https://python-all.ru/2.6/library/tempfile.html#module-tempfile) предоставляет функцию `mktemp()` для генерации уникальных имён временных файлов.415416```python417import tempfile418import os419420class Popen3:421    """422    Это безопасная с точки зрения взаимоблокировок версия popen, которая возвращает423    объект с errorlevel, out (строка) и err (строка).424    (capturestderr может не работать в Windows.)425    Пример: print Popen3('grep spam','\n\nhere spam\n\n').out426    """427    def __init__(self,command,input=None,capturestderr=None):428        outfile=tempfile.mktemp()429        command="( %s ) > %s" % (command,outfile)430        if input:431            infile=tempfile.mktemp()432            open(infile,"w").write(input)433            command=command+" <"+infile434        if capturestderr:435            errfile=tempfile.mktemp()436            command=command+" 2>"+errfile437        self.errorlevel=os.system(command) >> 8438        self.out=open(outfile,"r").read()439        os.remove(outfile)440        if input:441            os.remove(infile)442        if capturestderr:443            self.err=open(errfile,"r").read()444            os.remove(errfile)445```446447Имейте в виду, что многие интерактивные программы (например, vi) плохо работают, если вместо стандартного ввода и вывода подставлены каналы. Придётся использовать псевдотерминалы («ptys») вместо каналов. Или можно воспользоваться интерфейсом Python к библиотеке «expect» Дона Лайбса. Расширение Python для expect называется «expy» и доступно по адресу [http://expectpy.sourceforge.net](https://python-all.ru/2.6/faq/library.html). Чистое решение на Python, работающее как expect, – [pexpect](https://python-all.ru/2.6/faq/library.html).448449### [Как получить доступ к последовательному порту (RS232)?](https://python-all.ru/2.6/faq/library.html#id25)450451Для Win32, POSIX (Linux, BSD и т. д.), Jython:452453> [http://pyserial.sourceforge.net](https://python-all.ru/2.6/faq/library.html)454455Для Unix смотрите сообщение в Usenet от Митча Чепмена:456457> [http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com](https://python-all.ru/2.6/faq/library.html)458459### [Почему закрытие sys.stdout (stdin, stderr) на самом деле не закрывает его?](https://python-all.ru/2.6/faq/library.html#id26)460461Файловые объекты Python – это высокоуровневый слой абстракции над потоками C, которые, в свою очередь, являются среднеуровневым слоем абстракции над (в числе прочего) низкоуровневыми файловыми дескрипторами C.462463Для большинства файловых объектов, создаваемых в Python с помощью встроенного конструктора `file`, вызов `f.close()` помечает объект Python как закрытый с точки зрения Python, а также обеспечивает закрытие нижележащего C-потока. Это также происходит автоматически в деструкторе `f`, когда `f` становится мусором.464465Однако stdin, stdout и stderr обрабатываются Python особым образом из-за особого статуса, который им также присваивается в C. Вызов `sys.stdout.close()` помечает файловый объект на уровне Python как закрытый, но *не* закрывает связанный C-поток.466467Чтобы закрыть лежащий в основе поток C для одного из этих трёх, сначала стоит убедиться, что это действительно нужно (например, это может запутать расширения, пытающиеся выполнять ввод-вывод). Если всё же нужно, используйте os.close:468469```python470os.close(0)   # закрыть поток stdin C471os.close(1)   # закрыть поток stdout C472os.close(2)   # закрыть поток stderr C473```474475## [Сетевое и интернет-программирование](https://python-all.ru/2.6/faq/library.html#id27)476477### [Какие WWW-инструменты есть для Python?](https://python-all.ru/2.6/faq/library.html#id28)478479Смотрите главы [*Интернет-протоколы и поддержка*](https://python-all.ru/2.6/library/internet.html#internet) и [*Обработка интернет-данных*](https://python-all.ru/2.6/library/netdata.html#netdata) в Справочном руководстве по библиотеке Python. В Python есть много модулей, которые помогут создать веб-системы как на стороне сервера, так и на стороне клиента.480481Сводка доступных фреймворков поддерживается Полом Бодди на [http://wiki.python.org/moin/WebProgramming](https://python-all.ru/2.6/faq/library.html).482483Кэмерон Лэрд поддерживает полезный набор страниц о веб-технологиях Python по адресу [http://phaseit.net/claird/comp.lang.python/web\_python](https://python-all.ru/2.6/faq/library.html).484485### [Как имитировать отправку CGI-формы (METHOD=POST)?](https://python-all.ru/2.6/faq/library.html#id29)486487Мне нужно получать веб-страницы, которые появляются после отправки формы. Существует ли готовый код, позволяющий это сделать?488489Да. Вот простой пример с использованием httplib:490491```python492#!/usr/local/bin/python493494import httplib, sys, time495496### сформировать строку запроса497qs = "First=Josephine&MI=Q&Last=Public"498499### подключиться и отправить серверу путь500httpobj = httplib.HTTP('www.some-server.out-there', 80)501httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')502### теперь сгенерировать остальные заголовки HTTP...503httpobj.putheader('Accept', '*/*')504httpobj.putheader('Connection', 'Keep-Alive')505httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')506httpobj.putheader('Content-length', '%d' % len(qs))507httpobj.endheaders()508httpobj.send(qs)509### узнать, что сервер ответил...510reply, msg, hdrs = httpobj.getreply()511if reply != 200:512    sys.stdout.write(httpobj.getfile().read())513```514515Обратите внимание, что в общем случае для URL-кодированных POST-запросов строки запроса должны быть экранированы с помощью [`urllib.quote()`](https://python-all.ru/2.6/library/urllib.html#urllib.quote). Например, для отправки name=”Guy Steele, Jr.”:516517```python518>>> from urllib import quote519>>> x = quote("Guy Steele, Jr.")520>>> x521'Guy%20Steele,%20Jr.'522>>> query_string = "name="+x523>>> query_string524'name=Guy%20Steele,%20Jr.'525```526527### [Какой модуль использовать для генерации HTML?](https://python-all.ru/2.6/faq/library.html#id30)528529Доступно множество различных модулей:530531- HTMLgen – это библиотека классов объектов, соответствующих всем тегам разметки HTML 3.2. Она используется, когда вы пишете на Python и хотите синтезировать HTML-страницы для создания веб-сайта или для CGI-форм и т.д.532- DocumentTemplate и Zope Page Templates – это две разные системы, которые являются частью Zope.533- PTL от Quixote использует синтаксис Python для сборки строк текста.534535Дополнительные ссылки см. на [страницах вики по веб-программированию](https://python-all.ru/2.6/faq/library.html).536537### [Как отправить письмо из скрипта Python?](https://python-all.ru/2.6/faq/library.html#id31)538539Используйте модуль стандартной библиотеки [`smtplib`](https://python-all.ru/2.6/library/smtplib.html#module-smtplib).540541Вот очень простой интерактивный отправитель почты, использующий этот модуль. Этот метод будет\\nработать на любом хосте, поддерживающем SMTP-слушатель.542543```python544import sys, smtplib545546fromaddr = raw_input("From: ")547toaddrs  = raw_input("To: ").split(',')548print "Enter message, end with ^D:"549msg = ''550while True:551    line = sys.stdin.readline()552    if not line:553        break554    msg += line555556# Непосредственная отправка письма557server = smtplib.SMTP('localhost')558server.sendmail(fromaddr, toaddrs, msg)559server.quit()560```561562A 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:563564```python565SENDMAIL = "/usr/sbin/sendmail" # Расположение sendmail566import os567p = os.popen("%s -t -i" % SENDMAIL, "w")568p.write("To: receiver@example.com\n")569p.write("Subject: test\n")570p.write("\n") # Пустая строка, отделяющая заголовки от тела571p.write("Some text\n")572p.write("some more text\n")573sts = p.close()574if sts != 0:575    print "Sendmail exit status", sts576```577578### [Как избежать блокировки в методе connect() сокета?](https://python-all.ru/2.6/faq/library.html#id32)579580Модуль select часто используется для организации асинхронного ввода-вывода через сокеты.581582Чтобы предотвратить блокировку при TCP-подключении, можно перевести сокет в неблокирующий режим. Затем при вызове `connect()` соединение либо установится сразу (маловероятно), либо будет получено исключение, содержащее номер ошибки в виде `.errno`. `⟦`errno.EINPROGRESS указывает, что соединение устанавливается, но ещё не завершено. Разные ОС возвращают разные значения, поэтому необходимо проверить, что возвращается в вашей системе.583584Вы можете использовать метод `connect_ex()`, чтобы избежать исключения. Он просто возвращает значение errno. Для опроса можно вызвать `connect_ex()` позже – 0 или `errno.EISCONN` означают, что соединение установлено – или можно передать этот сокет в select, чтобы проверить, доступен ли он для записи.585586## [Базы данных](https://python-all.ru/2.6/faq/library.html#id33)587588### [Существуют ли интерфейсы к пакетам баз данных в Python?](https://python-all.ru/2.6/faq/library.html#id34)589590Да.591592Python 2.3 включает пакет [`bsddb`](https://python-all.ru/2.6/library/bsddb.html#module-bsddb), предоставляющий интерфейс к библиотеке BerkeleyDB. Интерфейсы к дисковым хешам, таким как [`DBM`](https://python-all.ru/2.6/library/dbm.html#module-dbm) и [`GDBM`](https://python-all.ru/2.6/library/gdbm.html#module-gdbm), также включены в стандартную поставку Python.593594Доступна поддержка большинства реляционных баз данных. Подробнее см. на [вики-странице DatabaseProgramming](https://python-all.ru/2.6/faq/library.html).595596### [Как реализовать постоянные объекты в Python?](https://python-all.ru/2.6/faq/library.html#id35)597598Библиотечный модуль [`pickle`](https://python-all.ru/2.6/library/pickle.html#module-pickle) решает эту задачу очень общим способом (хотя по-прежнему нельзя сохранять такие вещи, как открытые файлы, сокеты или окна), а библиотечный модуль [`shelve`](https://python-all.ru/2.6/library/shelve.html#module-shelve) использует pickle и (g)dbm для создания постоянных отображений, содержащих произвольные объекты Python. Для лучшей производительности можно использовать модуль [`cPickle`](https://python-all.ru/2.6/library/pickle.html#module-cPickle).599600Более неуклюжий способ – использовать младшую сестру pickle – модуль marshal. Модуль [`marshal`](https://python-all.ru/2.6/library/marshal.html#module-marshal) предоставляет очень быстрые способы сохранения нециклических базовых типов Python в файлы и строки и обратно. Хотя marshal не делает сложных вещей, таких как сохранение экземпляров или корректная обработка общих ссылок, он работает чрезвычайно быстро. Например, загрузка полмегабайта данных может занять менее трети секунды. Это часто оказывается быстрее, чем использовать что-то более сложное и универсальное, например gdbm с pickle/shelve.601602### [Почему cPickle такой медленный?](https://python-all.ru/2.6/faq/library.html#id36)603604Формат по умолчанию, используемый модулем pickle, медленный, но даёт читаемые пиклы. Сделать его форматом по умолчанию? Но это нарушит обратную совместимость:605606```python607largeString = 'z' * (100 * 1024)608myPickle = cPickle.dumps(largeString, protocol=1)609```610611### [Если моя программа аварийно завершилась с открытой базой данных bsddb (или anydbm), она повреждается. Почему?](https://python-all.ru/2.6/faq/library.html#id37)612613Databases 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.614615Если вы инициализировали новую базу данных bsddb, но ничего в неё не записали до сбоя программы, в результате часто остаётся файл нулевой длины, и при следующем открытии возникнет исключение.616617### [Я попытался открыть файл Berkeley DB, но bsddb выдаёт bsddb.error: (22, ‘Invalid argument’). Помогите! Как восстановить мои данные?](https://python-all.ru/2.6/faq/library.html#id38)618619Не паникуйте! Ваши данные, скорее всего, целы. Самая частая причина ошибки – попытка открыть более старый файл Berkeley DB с более новой версией библиотеки Berkeley DB.620621Во многих системах Linux теперь доступны все три версии Berkeley DB. Если вы переходите с версии 1 на более новую, используйте db\_dump185 для создания текстового дампа базы данных. Если вы переходите с версии 2 на версию 3, используйте db2\_dump для создания текстовой версии базы данных. В любом случае используйте db\_load для создания новой родной базы данных для последней версии, установленной на вашем компьютере. Если у вас установлена версия 3 Berkeley DB, вы сможете использовать db2\_load для создания родной базы данных версии 2.622623Следует отказаться от файлов Berkeley DB версии 1, поскольку код хэш-файлов содержит известные ошибки, которые могут повредить ваши данные.624625## [Математика и численные методы](https://python-all.ru/2.6/faq/library.html#id39)626627### [Как генерировать случайные числа в Python?](https://python-all.ru/2.6/faq/library.html#id40)628629Стандартный модуль [`random`](https://python-all.ru/2.6/library/random.html#module-random) реализует генератор случайных чисел. Использование простое:630631```python632import random633random.random()634```635636Возвращает случайное число с плавающей запятой в диапазоне \[0, 1).637638В этом модуле также есть много других специализированных генераторов, например:639640- `randrange(a, b)` выбирает целое число в диапазоне \[a, b).641- `uniform(a, b)` выбирает число с плавающей точкой в диапазоне \[a, b).642- `normalvariate(mean, sdev)` возвращает случайное число из нормального (гауссова) распределения.643644Некоторые функции более высокого уровня работают непосредственно с последовательностями, например:645646- `choice(S)` выбирает случайный элемент из заданной последовательности647- `shuffle(L)` перемешивает список на месте, т.е. переставляет его элементы случайным образом648649Также существует класс `Random`, который можно инстанцировать для создания нескольких независимых генераторов случайных чисел.650