Скрипты на Python
Это заметки по удобному и эффективному написанию небольших скриптов на Python. Возможно, потом они примут вид howto.
Простейший скрипт
Этот скрипт запускает процесс Java Web Start и грузит игру CGoban 3, замещая свой процесс интерпретатора:
1 2 3 4 5 | #!/usr/bin/env python import os url = 'http://files.gokgs.com/javaBin/cgoban.jnlp' os.execvp('javaws', ['javaws', url]) |
На Bash это выглядело бы так:
1 2 3 4 | #!/bin/bash url='http://files.gokgs.com/javaBin/cgoban.jnlp' exec javaws "$url" |
А раз различий не так много, почему бы не писать на хорошем языке Python вместо Bash? Замечу, что в случае с простыми конвейерами Bash удобнее, но так бывает не всегда.
Простой скрипт
TODO: Привести пример пары простых скриптов
Сложный скрипт
TODO: Привести пример сложного скрипта с разными фичами
Советы
- Внешие программы
- Для вызова внешних программ используйте
subprocess - Всегда проверяйте код завершения внешних процессов, здесь можно упростить обработку за счёт исключений
- Аналогом
execиз bash являетсяos.execv
- Для вызова внешних программ используйте
- Обработка ошибок
- Не выводите на консоль ничего лишнего, если всё в порядке
- Спрячьте стек вызовов при ошибке. Показывайте его при опции
-vили--debug - Если скрипт не может продолжать работу, завершайте его, выведя в
stderrразумное сообщение и вернув ненулевой код завершения - Если ошибка некритична, поругайтесь в
stderrи восстановитесь после этой ошибки - Не проверяйте наличие нужных файлов, открывайте их и обрабатывайте ошибки открытия
- Опции и настройки
- Используйте
optparseдля разбора опций даже в маленьких скриптах - Подумайте о превращении вашей программы в фильтр между
stdinиstdout - Если скрипт принимает входной файл как параметр, сделайте возможным
передачу любого числа имён файлов и файл со специальным именем
-для чтения изstdin - Если скрипту нужны настройки, подумайте об опциях командной строки, переменных окружения или же файлах конфигурации
- Форматом файла конфигурации скрипта можно сделать
- INI (
ConfigParser) - JSON (
json) - XML (
xml.etree.ElementTree) - Python (исполняйте файлы через
exec)
- INI (
- Предусмотрите системный и пользовательский файл конфигурации
- Используйте
- Строки и байты
- Если вы не трогаете кодировку в системном модуле
site, предусмотрите возможность задания кодировки для ввода-вывода - Помните, что байты — это не строки, а их сериализация. Используйте
encodeиdecodeдля преобразований между ними - В текстовые файлы пишут строки, а в бинарные — байты.
stdinи т. п. по умолчанию строковые, для бинарного ввода-вывода их нужно переоткрыть
- Если вы не трогаете кодировку в системном модуле
- Безопасность
- Указывайте полные пути внешних исполняемых файлов, не используйте
shell=Trueдляsubprocess - При использовании файлов конфигурации на Python помните, что в них может быть произвольный код
- Если для выполнения скрипта требуются права
root, прочитайте книгу по безопасности в Unix и перепроверьте скрипт 10 раз
- Указывайте полные пути внешних исполняемых файлов, не используйте
- Разработка и развёртывание
- Храните исходные коды скрипта в Mercurial
- Для скриптов среднего размера создайте простую систему функциональных тестов, добавляйте новые тесты по ходу разработки
- Для неочевидных алгоритмов пишите unit-тесты
- Подумайте над тем, чтобы увлечься Test Driven Development (TDD)
- Укажите в исходниках автора и лицензию (свободную, конечно же)
- Напишите хотя бы простейшую документацию в
README - Соберите пакет установки Python Egg с помощью
setuptools, соберите пакетPKGBUILDдля Arch Linux
- Разное
- Для скриптов среднего размера подумайте об использованиии
logging - Для скриптов сисадминства
loggingможет быть полезен возможностью интеграции сsyslogи ведения файлов логов с форматированными запиями - Присылайте отзывы и обновления этих советов
- Для скриптов среднего размера подумайте об использованиии
blog comments powered by Disqus
