Содержание страницы
Часто задаваемые вопросы по библиотекам и расширениям¶Library and Extension FAQ
Содержание
FAQ по библиотекам и расширениям
-
Где находится исходный файл math.py (socket.py, regex.py и т.д.)?Where is the math.py (socket.py, regex.py, etc.) source file?
Как сделать скрипт Python исполняемым в Unix?How do I make a Python script executable on Unix?
Существует ли пакет curses/termcap для Python?Is there a curses/termcap package for Python?
Есть ли в Python эквивалент onexit() из C?Is there an equivalent to C’s onexit() in Python?
Почему не работают мои обработчики сигналов?Why don’t my signal handlers work?
-
Как создать документацию из строк документации?How do I create documentation from doc strings?
Как получить одиночное нажатие клавиши?How do I get a single keypress at a time?
-
Ни один из моих потоков не запускается: почему?None of my threads seem to run: why?
Как распределить работу между несколькими рабочими потоками?How do I parcel out work among a bunch of worker threads?
Какие виды изменения глобальных значений являются потокобезопасными?What kinds of global value mutation are thread-safe?
Нельзя ли избавиться от глобальной блокировки интерпретатора (GIL)?Can’t we get rid of the Global Interpreter Lock?
-
Как скопировать файл?How do I copy a file?
Как читать (или записывать) двоичные данные?How do I read (or write) binary data?
Не удаётся использовать os.read() на канале, созданном с помощью os.popen(); почему?I can’t seem to use os.read() on a pipe created with os.popen(); why?
Как получить доступ к последовательному порту (RS232)?How do I access the serial (RS232) port?
Почему закрытие sys.stdout (stdin, stderr) на самом деле не закрывает его?Why doesn’t closing sys.stdout (stdin, stderr) really close it?
Сетевое и интернет-программирование
Как имитировать отправку CGI-формы (METHOD=POST)?How can I mimic CGI form submission (METHOD=POST)?
Какой модуль использовать для генерации HTML?What module should I use to help with generating HTML?
Как отправить письмо из скрипта Python?How do I send mail from a Python script?
Как избежать блокировки в методе connect() сокета?How do I avoid blocking in the connect() method of a socket?
-
Как реализовать постоянные объекты в Python?How do you implement persistent objects in Python?
-
Общие вопросы по библиотекам¶General Library Questions
Как найти модуль или приложение для выполнения задачи X?¶How do I find a module or application to perform task X?
Проверьте справочник библиотеки, чтобы узнать, есть ли подходящий модуль в стандартной библиотеке. (Со временем вы запомните, что входит в стандартную библиотеку, и сможете пропустить этот шаг.)
Для сторонних пакетов поищите в Python Package Index или попробуйте Google или другой поисковик. Поиск по слову «Python» плюс одно-два ключевых слова по вашей теме обычно даёт полезные результаты.
Где находится исходный файл math.py (socket.py, regex.py и т. д.)?¶Where is the math.py (socket.py, regex.py, etc.) source file?
Если не удаётся найти исходный файл модуля, возможно, он встроенный или
динамически загружаемый модуль, реализованный на C, C++ или другом компилируемом языке.
В этом случае исходного файла может не быть, или он находится, например, в
mathmodule.c, где-то в каталоге с исходниками на C (не на Python Path).
В Python существует (как минимум) три вида модулей:
модули, написанные на Python (.py);
модули, написанные на C и динамически загружаемые (.dll, .pyd, .so, .sl и т. д.);
модули, написанные на C и связанные с интерпретатором; чтобы получить их список, введите:
import sys print(sys.builtin_module_names)
Как сделать скрипт Python исполняемым в Unix?¶How do I make a Python script executable on Unix?
Нужно сделать две вещи: установить исполняемый режим для файла скрипта и
убедиться, что первая строка начинается с #!, за которым следует путь к интерпретатору
Python.
Первое выполняется командой chmod +x scriptfile или, возможно, chmod 755
scriptfile.
Второе можно сделать несколькими способами. Самый простой – написать
#!/usr/local/bin/python
в самой первой строке файла, указав путь к установленному на вашей платформе интерпретатору Python.
Если вы хотите, чтобы скрипт не зависел от расположения интерпретатора
Python, используйте программу env. Почти все варианты Unix поддерживают
следующее, при условии, что интерпретатор Python находится в каталоге, входящем в
PATH пользователя:
#!/usr/bin/env python
Не делайте этого для CGI-скриптов. Переменная PATH для CGI-скриптов
часто очень ограничена, поэтому нужно указывать полный абсолютный путь к
интерпретатору.
Иногда окружение пользователя настолько переполнено, что программа /usr/bin/env завершается с ошибкой; или программы env вообще нет. В таком случае можно попробовать следующий трюк (благодаря Алексу Резински):
#! /bin/sh
""":"
exec python $0 ${1+"$@"}
"""
Небольшой недостаток в том, что при этом определяется строка документации __doc__ скрипта. Однако это можно исправить, добавив
__doc__ = """...Whatever..."""
Существует ли пакет curses/termcap для Python?¶Is there a curses/termcap package for Python?
Для вариантов Unix: стандартный дистрибутив исходного кода Python поставляется с модулем curses в подкаталоге Modules, хотя по умолчанию он не компилируется. (Обратите внимание, что в дистрибутиве Windows его нет – модуля curses для Windows не существует.)
Модуль curses поддерживает базовые возможности curses, а также многие дополнительные
функции из ncurses и SYSV curses, такие как цвет, поддержка альтернативных наборов
символов, подокна и поддержка мыши. Это означает, что модуль несовместим с
операционными системами, где есть только BSD curses, но сейчас, похоже, нет
поддерживаемых ОС, попадающих в эту категорию.
Есть ли в Python аналог onexit() из C?¶Is there an equivalent to C’s onexit() in Python?
Модуль atexit предоставляет функцию register, похожую на onexit() из C.
Почему не работают мои обработчики сигналов?¶Why don’t my signal handlers work?
Самая распространённая проблема – обработчик сигнала объявлен с неправильным списком аргументов. Он вызывается как
handler(signum, frame)
поэтому его следует объявлять с двумя параметрами:
def handler(signum, frame):
...
Типовые задачи¶Common tasks
Как тестировать программу или компонент Python?¶How do I test a Python program or component?
В состав Python входят две тестовые платформы. Модуль doctest находит
примеры в строках документации модуля и запускает их, сравнивая вывод с
ожидаемым выводом, указанным в строке документации.
Модуль unittest – это более продвинутая тестовая платформа, созданная по образцу
тестовых платформ Java и Smalltalk.
Чтобы упростить тестирование, используйте в программе хорошую модульную архитектуру. Почти вся функциональность должна быть инкапсулирована в функции или методы классов – и это иногда неожиданно и приятно ускоряет работу программы (потому что доступ к локальным переменным быстрее, чем к глобальным). Кроме того, программа не должна зависеть от изменения глобальных переменных, поскольку это сильно усложняет тестирование.
«Глобальная основная логика» вашей программы может быть такой же простой, как
if __name__ == "__main__":
main_logic()
в конце главного модуля программы.
Когда программа организована как удобная совокупность функций и классов, следует написать тестовые функции, проверяющие их поведение. Набор тестов, автоматизирующий последовательность проверок, можно связать с каждым модулем. Это кажется большой работой, но благодаря лаконичности и гибкости Python это на удивление легко. Можно сделать написание кода гораздо приятнее и увлекательнее, если писать тестовые функции параллельно с «рабочим кодом», так как это позволяет раньше находить ошибки и даже конструктивные недочёты.
«Вспомогательные модули», не предназначенные для роли главного модуля программы, могут включать самопроверку модуля.
if __name__ == "__main__":
self_test()
Даже программы, взаимодействующие со сложными внешними интерфейсами, могут быть протестированы в отсутствие этих интерфейсов с помощью «фиктивных» интерфейсов, реализованных на Python.
Как создавать документацию из строк документации?¶How do I create documentation from doc strings?
Модуль pydoc может создавать HTML из строк документации в исходном коде Python. Альтернативой для создания API-документации исключительно по docstrings является epydoc. Sphinx также может включать содержимое docstring.
Как получить нажатие одной клавиши за раз?¶How do I get a single keypress at a time?
Для Unix-подобных систем есть несколько решений. Это несложно сделать с помощью curses, но curses – довольно большой модуль для изучения.
Потоки¶Threads
Как программировать с помощью потоков?¶How do I program using threads?
Обязательно используйте модуль threading, а не модуль _thread. Модуль threading создаёт удобные абстракции поверх низкоуровневых примитивов, предоставляемых модулем _thread.
Почему ни один из моих потоков не выполняется?¶None of my threads seem to run: why?
Как только главный поток завершается, все потоки уничтожаются. Главный поток выполняется слишком быстро, не давая потокам времени на работу.
Простое исправление – добавить в конец программы задержку, достаточно длинную для завершения всех потоков:
import threading, time
def thread_task(name, n):
for i in range(n):
print(name, i)
for i in range(10):
T = threading.Thread(target=thread_task, args=(str(i), i))
T.start()
time.sleep(10) # <---------------------------!
Но теперь (на многих платформах) потоки не выполняются параллельно, а, похоже, выполняются последовательно, один за другим! Причина в том, что планировщик потоков ОС не запускает новый поток, пока предыдущий не заблокирован.
Простое исправление – добавить небольшую задержку в начало функции run:
def thread_task(name, n):
time.sleep(0.001) # <--------------------!
for i in range(n):
print(name, i)
for i in range(10):
T = threading.Thread(target=thread_task, args=(str(i), i))
T.start()
time.sleep(10)
Вместо попыток угадать подходящее значение задержки для time.sleep() лучше использовать какой-нибудь семафорный механизм. Одна из идей – использовать модуль queue для создания объекта очереди, позволить каждому потоку добавлять токен в очередь по завершении, а главному потоку – читать из очереди столько токенов, сколько потоков.
Как распределить работу между несколькими рабочими потоками?¶How do I parcel out work among a bunch of worker threads?
Самый простой способ – использовать модуль concurrent.futures, особенно класс ThreadPoolExecutor.
Или, если требуется тонкий контроль над алгоритмом распределения, можно написать собственную логику вручную. Используйте модуль queue для создания очереди со списком заданий. Класс Queue поддерживает список объектов и имеет метод .put(obj), добавляющий элементы в очередь, и метод .get(), возвращающий их. Класс позаботится о блокировках, необходимых, чтобы каждое задание было выдано ровно один раз.
Вот простой пример:
import threading, queue, time
# Рабочий поток забирает задания из очереди. Когда очередь пуста, он
# предполагает, что больше работы не будет, и завершается.
# (На практике рабочие потоки работают до принудительного завершения.)
def worker():
print('Running worker')
time.sleep(0.1)
while True:
try:
arg = q.get(block=False)
except queue.Empty:
print('Worker', threading.current_thread(), end=' ')
print('queue empty')
break
else:
print('Worker', threading.current_thread(), end=' ')
print('running with argument', arg)
time.sleep(0.5)
# Создать очередь
q = queue.Queue()
# Запустить пул из 5 рабочих потоков
for i in range(5):
t = threading.Thread(target=worker, name='worker %i' % (i+1))
t.start()
# Начать добавление заданий в очередь
for i in range(50):
q.put(i)
# Дать потокам время на выполнение
print('Main thread sleeping')
time.sleep(5)
При запуске это выдаст следующий вывод:
Running worker
Running worker
Running worker
Running worker
Running worker
Main thread sleeping
Worker <Thread(worker 1, started 130283832797456)> running with argument 0
Worker <Thread(worker 2, started 130283824404752)> running with argument 1
Worker <Thread(worker 3, started 130283816012048)> running with argument 2
Worker <Thread(worker 4, started 130283807619344)> running with argument 3
Worker <Thread(worker 5, started 130283799226640)> running with argument 4
Worker <Thread(worker 1, started 130283832797456)> running with argument 5
...
Обратитесь к документации модуля за подробностями; класс Queue предоставляет многофункциональный интерфейс.
Какие виды изменения глобальных значений потокобезопасны?¶What kinds of global value mutation are thread-safe?
Внутренне используется глобальная блокировка интерпретатора (GIL), чтобы гарантировать, что в виртуальной машине Python одновременно выполняется только один поток. В общем случае Python переключается между потоками только между инструкциями байткода; частота переключений задаётся через sys.setswitchinterval(). Таким образом, каждая инструкция байткода и, следовательно, весь реализованный на C код, вызываемый из этой инструкции, атомарны с точки зрения программы на Python.
Теоретически это означает, что точный учёт требует точного понимания реализации байткода виртуальной машины Python. На практике это означает, что операции над совместно используемыми переменными встроенных типов (int, list, dict и т.д.), которые «выглядят атомарными», действительно атомарны.
Например, следующие операции атомарны (L, L1, L2 – списки, D, D1, D2 – словари, x, y – объекты, i, j – целые числа):
L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()
А эти – нет:
i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1
Операции, заменяющие другие объекты, могут вызывать метод __del__() этих объектов, когда счётчик ссылок достигает нуля, и это может повлиять на другие вещи. Особенно это касается массовых обновлений словарей и списков. Если есть сомнения, используйте мьютекс!
Нельзя ли избавиться от глобальной блокировки интерпретатора?¶Can’t we get rid of the Global Interpreter Lock?
Глобальная блокировка интерпретатора (GIL) часто считается помехой для развёртывания Python на высокопроизводительных многопроцессорных серверных машинах, поскольку многопоточная программа на Python фактически использует только один процессор из-за требования, что (почти) весь код Python может выполняться только при удерживаемом GIL.
Во времена Python 1.5 Грег Стайн реализовал обширный набор патчей (так называемые «free threading» патчи), который удалял GIL и заменял его более мелкозернистой блокировкой. Недавно Адам Олсен провёл похожий эксперимент в своём проекте python-safethread. К сожалению, оба эксперимента продемонстрировали резкое падение производительности в однопоточном режиме (как минимум на 30%), из-за большого количества мелкозернистых блокировок, необходимых для компенсации удаления GIL.
Это не значит, что Python нельзя эффективно использовать на многопроцессорных машинах! Просто нужно подойти творчески и разделять работу между несколькими процессами, а не несколькими потоками. Класс ProcessPoolExecutor из нового модуля concurrent.futures предоставляет простой способ сделать это; модуль multiprocessing предоставляет API более низкого уровня, если требуется более тонкий контроль над распределением задач.
Разумное использование расширений на C также может помочь; если
используется расширение на C для выполнения трудоёмкой задачи, оно может
освободить GIL, пока поток выполнения находится в C-коде, и позволить
другим потокам выполнять работу. Некоторые модули стандартной библиотеки,
такие как zlib и hashlib, уже так делают.
Высказывались предложения сделать GIL блокировкой на уровне состояния интерпретатора, а не глобальной; тогда интерпретаторы не смогли бы обмениваться объектами. К сожалению, это тоже вряд ли произойдёт. Это потребовало бы огромного объёма работы, поскольку многие реализации объектов в настоящее время используют глобальное состояние. Например, небольшие целые числа и короткие строки кэшируются; эти кэши пришлось бы перенести в состояние интерпретатора. Другие типы объектов имеют свои собственные списки свободной памяти; эти списки также пришлось бы перенести. И так далее.
И я сомневаюсь, что это вообще можно сделать за конечное время, потому что та же проблема существует и для сторонних расширений. Скорее всего, сторонние расширения пишутся быстрее, чем вы успеваете переделывать их для хранения всего глобального состояния в состоянии интерпретатора.
И наконец, если у вас есть несколько интерпретаторов, не разделяющих состояние, что вы выигрываете по сравнению с запуском каждого интерпретатора в отдельном процессе?
Ввод и вывод¶Input and Output
Как удалить файл? (И другие вопросы о файлах…)¶How do I delete a file? (And other file questions…)
Используйте os.remove(filename) или os.unlink(filename); документацию смотрите в модуле os.
Эти две функции идентичны; unlink() – просто имя системного вызова Unix
для этой функции.
Чтобы удалить каталог, используйте os.rmdir(); для создания используйте
os.mkdir(). os.makedirs(path) создаст все промежуточные каталоги в path, которые
не существуют. os.removedirs(path) удалит промежуточные каталоги, если они пусты;
если нужно удалить всё дерево каталогов и его содержимое, используйте
shutil.rmtree().
Чтобы переименовать файл, используйте os.rename(old_path, new_path).
Чтобы урезать файл, откройте его с помощью f = open(filename, "rb+") и используйте f.truncate(offset);
смещение по умолчанию равно текущей позиции. Также есть os.ftruncate(fd, offset) для
файлов, открытых с помощью os.open(), где fd – это файловый
дескриптор (небольшое целое число).
Модуль shutil также содержит ряд функций для работы с файлами, включая
copyfile(), copytree() и rmtree().
Как скопировать файл?¶How do I copy a file?
Модуль shutil содержит функцию copyfile(). Обратите внимание, что на томах
NTFS в Windows она не копирует альтернативные потоки данных,
а на томах HFS+ в macOS – ресурсные форки, хотя оба сейчас
редко используются. Она также не копирует права доступа к файлам и
метаданные, однако использование shutil.copy2() вместо неё сохранит большую их
часть (но не всё).
Как читать (или записывать) двоичные данные?¶How do I read (or write) binary data?
Для чтения или записи сложных двоичных форматов данных лучше всего
использовать модуль struct. Он позволяет взять строку, содержащую
двоичные данные (обычно числа), и преобразовать её в объекты Python;
и наоборот.
Например, следующий код читает из файла два 2-байтовых целых числа и одно 4-байтовое целое число в формате big-endian:
import struct
with open(filename, "rb") as f:
s = f.read(8)
x, y, z = struct.unpack(">hhl", s)
Символ ‘>’ в строке формата указывает на порядок байтов big-endian; буква ‘h’ читает одно «короткое целое» (2 байта), а ‘l’ – одно «длинное целое» (4 байта) из строки.
Для данных, которые являются более регулярными (например, однородный
список целых или чисел с плавающей запятой), можно также использовать
модуль array.
Не удаётся использовать os.read() для канала, созданного с помощью os.popen(); почему?¶I can’t seem to use os.read() on a pipe created with os.popen(); why?
os.read() – это низкоуровневая функция, которая принимает файловый дескриптор
– небольшое целое число, представляющее открытый файл. os.popen() создаёт
высокоуровневый файловый объект того же типа, что возвращается встроенной
функцией open(). Таким образом, чтобы прочитать n байт из
канала p, созданного с помощью os.popen(), нужно использовать
p.read(n).
Как получить доступ к последовательному порту (RS232)?¶How do I access the serial (RS232) port?
Для Win32, OSX, Linux, BSD, Jython, IronPython:
Для Unix смотрите сообщение в Usenet от Митча Чепмена:
Почему закрытие sys.stdout (stdin, stderr) на самом деле не закрывает его?¶Why doesn’t closing sys.stdout (stdin, stderr) really close it?
Python file objects are a high-level layer of abstraction on low-level C file descriptors.
Для большинства файловых объектов, создаваемых в Python через встроенную
функцию open(), f.close() помечает файловый объект Python как закрытый
с точки зрения Python, а также организует закрытие нижележащего файлового
дескриптора C. Это также происходит автоматически в деструкторе f,
когда f становится мусором.
Но stdin, stdout и stderr обрабатываются Python особым образом из-за
особого статуса, присвоенного им также в C. Вызов sys.stdout.close() помечает
файловый объект на уровне Python как закрытый, но не закрывает
связанный файловый дескриптор C.
Чтобы закрыть нижележащий файловый дескриптор C для одного из этих трёх,
сначала следует убедиться, что это действительно нужно сделать (например,
можно запутать модули расширений, пытающиеся выполнять ввод-вывод). Если
это так, используйте os.close():
os.close(stdin.fileno())
os.close(stdout.fileno())
os.close(stderr.fileno())
Или можно использовать числовые константы 0, 1 и 2 соответственно.
Сетевое и интернет-программирование¶Network/Internet Programming
Какие WWW-инструменты есть для Python?¶What WWW tools are there for Python?
Смотрите главы Интернет-протоколы и поддержка и Обработка интернет-данных в Справочном руководстве по библиотеке Python. В Python есть много модулей, которые помогут создать веб-системы как на стороне сервера, так и на стороне клиента.
Сводка доступных фреймворков поддерживается Полом Бодди на\nhttps://wiki.python.org/moin/WebProgramming.
Кэмерон Лэрд поддерживает полезный набор страниц о веб-технологиях Python по адресу https://web.archive.org/web/20210224183619/http://phaseit.net/claird/comp.lang.python/web_python.
Как имитировать отправку CGI-формы (METHOD=POST)?¶How can I mimic CGI form submission (METHOD=POST)?
Мне нужно получать веб-страницы, которые появляются после отправки формы. Существует ли готовый код, позволяющий это сделать?
Да. Вот простой пример использования urllib.request:
#!/usr/local/bin/python
import urllib.request
# сформировать строку запроса
qs = "First=Josephine&MI=Q&Last=Public"
# подключиться и отправить серверу путь
req = urllib.request.urlopen('http://www.some-server.out-there'
'/cgi-bin/some-cgi-script', data=qs)
with req:
msg, hdrs = req.read(), req.info()
Обратите внимание, что в целом для POST-операций с процентным кодированием строки запроса должны быть экранированы с помощью urllib.parse.urlencode(). Например, чтобы отправить name=Guy Steele, Jr.:
>>> import urllib.parse
>>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'})
'name=Guy+Steele%2C+Jr.'
См. также
Руководство по получению интернет-ресурсов с помощью пакета urllib с многочисленными примерами.
Какой модуль использовать для генерации HTML?¶What module should I use to help with generating HTML?
Вы можете найти подборку полезных ссылок на вики-странице Web Programming.
Как отправить письмо из скрипта Python?¶How do I send mail from a Python script?
Используйте модуль стандартной библиотеки smtplib.
Вот очень простой интерактивный отправитель почты, использующий этот модуль. Этот метод будет\nработать на любом хосте, поддерживающем SMTP-слушатель.
import sys, smtplib
fromaddr = input("From: ")
toaddrs = input("To: ").split(',')
print("Enter message, end with ^D:")
msg = ''
while True:
line = sys.stdin.readline()
if not line:
break
msg += line
# Непосредственная отправка письма
server = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
Альтернатива, доступная только в Unix, использует sendmail. Расположение программы sendmail различается в разных системах: иногда это /usr/lib/sendmail, иногда\n/usr/sbin/sendmail. Страница руководства sendmail поможет разобраться. Вот пример кода:
import os
SENDMAIL = "/usr/sbin/sendmail" # Расположение sendmail
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: receiver@example.com\n")
p.write("Subject: test\n")
p.write("\n") # Пустая строка, отделяющая заголовки от тела
p.write("Some text\n")
p.write("some more text\n")
sts = p.close()
if sts != 0:
print("Sendmail exit status", sts)
Как избежать блокировки в методе connect() сокета?¶How do I avoid blocking in the connect() method of a socket?
Модуль select обычно используется для асинхронного ввода-вывода на сокетах.
Чтобы предотвратить блокировку при TCP-подключении, можно перевести сокет в неблокирующий режим. Затем при вызове socket.connect() соединение либо установится сразу (маловероятно), либо будет получено исключение, содержащее номер ошибки в .errno. errno.EINPROGRESS означает, что соединение устанавливается, но ещё не завершено. В разных ОС возвращаются разные значения, поэтому потребуется проверить, что возвращается в вашей системе.
Можно использовать метод socket.connect_ex(), чтобы избежать создания исключения. Он просто вернёт значение errno. Для опроса можно вызвать socket.connect_ex() повторно позже – 0 или errno.EISCONN означают, что соединение установлено – или передать этот сокет в select.select(), чтобы проверить, доступен ли он для записи.
Базы данных¶Databases
Существуют ли интерфейсы к пакетам баз данных в Python?¶Are there any interfaces to database packages in Python?
Да.
Интерфейсы к дисковым хешам, таким как DBM и GDBM, также включены в стандартный Python. Также есть модуль sqlite3, предоставляющий лёгкую дисковую реляционную базу данных.
Доступна поддержка большинства реляционных баз данных. Подробнее см. на вики-странице DatabaseProgramming.
Как реализовать постоянные объекты в Python?¶How do you implement persistent objects in Python?
Модуль библиотеки pickle решает эту задачу очень общим способом (хотя\nвсё ещё нельзя хранить такие вещи, как открытые файлы, сокеты или окна), а модуль shelve использует pickle и (g)dbm для создания постоянных отображений, содержащих произвольные объекты Python.
Математика и численные методы¶Mathematics and Numerics
Как генерировать случайные числа в Python?¶How do I generate random numbers in Python?
Стандартный модуль random реализует генератор случайных чисел. Использовать его просто:
import random
random.random()
Возвращает случайное число с плавающей запятой в диапазоне [0, 1).
В этом модуле также есть много других специализированных генераторов, например:
randrange(a, b)выбирает целое число в диапазоне [a, b).uniform(a, b)выбирает число с плавающей запятой в диапазоне [a, b).normalvariate(mean, sdev)делает выборку из нормального (гауссова) распределения.
Некоторые функции более высокого уровня работают непосредственно с последовательностями, например:
choice(S)выбирает случайный элемент из заданной последовательности.shuffle(L)перемешивает список на месте, то есть переставляет его элементы случайным образом.
Также существует класс Random, экземпляр которого можно создать для получения независимых
генераторов случайных чисел.