- 1
- Генерирует универсальный идентификатор на основе имени компьютера и текущего времени
- 2
- Генерирует случайный идентификатор
662868cc-ce85-11f0-9e8f-586c259e21c2
ccafcd42-0589-4579-b960-ccbd6bb82156
На этом занятии мы с вами обсудим основные библиотеки из стандартного набора в Python, их назначение и применение. Здесь будет представлен далеко не весь перечень, а те библиотеки, которые вам могут понадобится для решения текущих жизненных задач с поправкой на имеющийся у вас на данный момент времени опыт. Структура этой главы будет напоминать FAQ (Frequently Asked Questions, часто задаваемые вопросы).
Часто в качестве идентификаторов используют либо порядковые числа, либо некоторую позиционно закодированную строку (каждая позиция несет определенный смысл). Такой подход хорош в условиях небольшого количества данных, которые хранятся централизовано и к которые часто используют люди. Если же нам необходимо или хранение больших массивов данных, или к которым не будет иметь прямого доступа человек, или данные которые будут хранится распределенно, то обесспечить уникальность идентификаторов подобным образом будет сложно. Для этого нужна библиотека uuid (универсальный уникальный идентификатор). Примеры использования показаны на Listing 18.1. Результат - уникальное 128-битное значение.
Дата и время представляют собой особый тип данных со своим особым спектром операций. На машинном уровне работа с датами осуществляется довольно просто. Согласно стандарту POSIX текущее дата и время определяется как число секунд, прошедших с полуночи 1 января 1970 года по Гринвичу (UTC+0). Операции над датой и временем работают как обычные арифметические операции. Для человека такой формат неудобен, т.к. необходимо оперировать днями, месяцами, учитывать разницу в часовых поясах и календарных системах, високосные кода. В этом нам поможет библиотека datetime. Смотри на Listing 18.2.
from datetime import datetime, timedelta
skynet_critical = "29.08.1997 02:14:53"
1skynet_critical_date = datetime.strptime(skynet_critical, "%d.%m.%Y %H:%M:%S")
2today = datetime.now()
3time_left = today - skynet_critical_date
4print(today.strftime("%Y-%m-%d %H:%M:%S"))
5print(time_left)
6print(today.year)
7meeting_time = datetime(2025, 6, 19, 15, 0, 0)
8reminder_time = meeting_time - timedelta(minutes=30)
print(reminder_time.strftime("%Y-%m-%d %H:%M:%S"))strftime
2025-12-01 10:14:38
10321 days, 7:59:45.844084
2025
2025-06-19 14:30:00
Для работы с календарем существует модуль calendar. Примеры в Listing 18.3.
from datetime import datetime
import calendar
1print(calendar.month(2025, 12))
2print(calendar.isleap(2025))
today = datetime.now()
3print(calendar.weekday(today.year, today.month, today.day)) December 2025
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
False
0
При написании и дальнейшем использовании сложных программ возникает потребность отслеживания их выполнения для обнаружения внештатных ситуаций и причин их возникновения. Для этого в языках программирования есть возможность журналирования действий. Для этого существует модуль logging, пример использования которого вы увидете в Listing 18.4. logging поддерживает следующие возможности:
import logging
1logging.basicConfig(level=logging.INFO,format='%(levelname)s: %(message)s')
logging.info("This is an info message")
2logger = logging.getLogger("custom_logger")
logger.warning("This is a warning from custom_logger")Конфигурационные файлы в современном мире принято сохранять в двух форматах: JSON и YAML. Обработка формата yaml лежит за пределами стандартной библиотеки, а json формат является прямым аналогом питоновского словаря,поэтому в python удобно работать с json форматом, хранить в нем информацию об состояниях и конфигурации программы. Пример работы показан в Listing 18.5. Иногда бывает необходимо кэшировать сложные объекты, которые тяжело или невозможно представить в виде словаря и которые нужно передавать по сети распределенных вычислений. Для работы с такими данными рекомендуется использовать библиотеку pickle из Listing 18.6. Библиотека pickle использует механизм сериализации.
это процесс преобразования структуры данных (например, объекта в памяти) в поток байтов для сохранения или передачи.
Обратный процесс
import json
config_file = "user_config.json"
1with open(config_file, mode="r", encoding="utf-8") as file:
config = json.load(file)
2config["user"]["name"] = "Charlie"
config["user"]["preferences"]["theme"] = "dark"
3with open(config_file, mode="w", encoding="utf-8") as file:
json.dump(config, file, indent=4)
data = {"name": "Bob", "age": 25}
4json_str = json.dumps(data)
5data = json.loads('{"name": "Bob", "age": 25}')Загрузка сериализованных данных из ненадёжных источников может привести к выполнению произвольного кода, что представляет серьёзную угрозу безопасности. Загружать сериализованные данные следует только из надёжных источников!
Для минимизации ошибок, связанных с разной записиью путей в различных операционных системах, существует модуль pathlib, который реализует также часть продвинутого функционала, такой как глоббинг - прочесывание файловой системы на наличие файлов, соответствующих некоторому паттерну. Пример продемонстрирован в Listing 18.7. Эта библиотека позволяет в некоторых случаях не использовать функции из модуля os. Для высокоуровневой работы над файловой системой существует модуль shutil. Он позволяет копировать, перемещать, удалять, архивировать файлы и папки, проверять свободное место на диске перед операцией. Пример продемонстрирован на Listing 18.8.
from pathlib import Path
1bin = Path("/usr/bin")
2bin.exists()
dir = Path("new_folder")
3dir.mkdir()
dir.exists()
file = Path("example.txt")
4file.write_text("Hello, World!")
5file.read_text()
6for file in Path(".").iterdir():
print(file)
project_dir = Path("project")
7python_files = list(project_dir.rglob("*.py"))
python_filesЗапуск и обработка дочерних процесов (не путать с multiprocessing!) осуществляется с помощью модуля subprocess. Такой функционал крайне необходим в биоинформатике, когда необхходимо запустить написанную другим разработчиком утилиту. Пример показан на Listing 18.9.
import subprocess
1result = subprocess.run(["echo", "Hello, World!"], capture_output=True, text=True)
2print(result.stdout)
3result = subprocess.run("ls -l", capture_output=True, text=True, shell = True)
4process = subprocess.Popen(["cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
5output, _ = process.communicate("Hello from Popen!")
6print(output)Часто возникает ситуация, когда бывает нужен простой объект без специфичного поведения: только свойства и методы доступа к ним. Здесь на помощь к нам придут именованные кортежи из collections и dataclass из dataclasses. Именнованные кортежи исторически появились раньше, используют меньше памяти и создают immutable объекты. dataclass более новая особенность языка, которая обладает более аккуратным синтаксисом. Примеры представлены в Listing 18.10.
from dataclasses import dataclass
from collections import namedtuple
1@dataclass
class Circle:
2 radius: float = 1.0
circle = Circle()
print(circle.radius)
3Circle = namedtuple("Circle", ["radius"], defaults=[1.0])
circle = Circle()
print(circle.radius)1.0
1.0
Модуль collections также содержит имплементации нескольких полезных структур данных: отсортированный словарь, счётчик, двусторонюю очередь и другие. Пример использования счётчика продемонстрирован на Listing 18.11.
from collections import Counter, OrderedDict
text = "lorem ipsum dolor sit amet ipsum lorem"
word_counts = Counter(text.split())
ordered_word_counts = OrderedDict(word_counts.most_common())
ordered_word_countsOrderedDict([('lorem', 2),
('ipsum', 2),
('dolor', 1),
('sit', 1),
('amet', 1)])
import re
1pattern = r"\d+"
2print(re.findall(pattern, "There are 42 apples and 100 oranges"))
3match = re.search(pattern, "There are 42 apples")
4print(match.group(0))
5print(re.sub(pattern, "#", "Room 123, Floor 4"))
6print(re.split(r"\s+", "There are 42 apples and 100 oranges"))['42', '100']
42
Room #, Floor #
['There', 'are', '42', 'apples', 'and', '100', 'oranges']
Эффективная по памяти работа с комбинаторикой за счёт использования генераторов.
from itertools import cycle, combinations, permutations, chain
1print(list(chain([1, 2], [3, 4], [5, 6])))
2colors = cycle(["red", "green", "blue"])
print([next(colors) for _ in range(6)])
3print(list(combinations("ABC", 2)))
guests = ["Alice", "Bob", "Carol"]
4print(list(permutations(guests)))[1, 2, 3, 4, 5, 6]
['red', 'green', 'blue', 'red', 'green', 'blue']
[('A', 'B'), ('A', 'C'), ('B', 'C')]
[('Alice', 'Bob', 'Carol'), ('Alice', 'Carol', 'Bob'), ('Bob', 'Alice', 'Carol'), ('Bob', 'Carol', 'Alice'), ('Carol', 'Alice', 'Bob'), ('Carol', 'Bob', 'Alice')]
import hashlib
1hash_object = hashlib.md5(b"Real Python")
print(hash_object.hexdigest())
hash_object = hashlib.sha256()
2hash_object.update(b"Real ")
hash_object.update(b"Python")
print(hash_object.hexdigest())5245ae598714e551418aa6d5cc2cf5bc
4a2b42c72ead91c16165d81622a347d5d65addb3a6984927b8322af26827baf3
Если не устраивают ошибки округления при работе с числами с плавающей запятой, можно работать с рациональными числами как с обыкновенными дробями.
from fractions import Fraction
1ingredient_costs = [Fraction("1/3"), Fraction("2/5"), Fraction("1/2")]
total_cost = sum(ingredient_costs)
print(total_cost)37/30
Возьмите любое стихотворное произведение и подсчитайте в нём количество символов.
Отсортируйте словарь из п.1 и сохраните его в формате json.
Поделите количество символов на количество слов (обыкновенная дробь!) и сохраните в формате pkl
Рассчитайте количество времени, которое прошло со времени написания автором этого стихотворения. Какой это был день недели, был ли этот год високосным.
Из скольких слов состоит наидлиннейшее предложение? Рассчитайте от него хэш-функцию md5.
Прочитайте сохранённый файл pkl, удалите значения с ключами, которые не являются буквами и пересохраните в pkl.
Создайте класс Vector3D с помощью dataclass и именнованный кортеж с такими же полями. Реализуйте функцию для расчёта модуля вектора. Будет ли он одинаково работать с dataclass и namedtuple?
Получите все возможные сочетания значений двух шестигранных игральных кубиков.
Создайте папку и скопируйте туда созданные вами файлы.
Преобразуйте стихотворение в поток байтов и сохраните его в файл.