····'XDG_CACHE_HOME',
····os.path.join(os.path.expanduser('~'), '.cache')
)
Как вам узнать, что эти переменные существуют? Необходимость urllib.request.getproxies() обусловлена необязательными аргументами в requests.get(), поэтому часть этой информации доступна из сведений API о вызываемых вами библиотеках. Переменные среды зачастую нужны для определенной функциональности, поэтому, если библиотека предназначена для использования с конкретной базой данных или другим родственным приложением, в документации к этим приложениям будут перечислены актуальные переменные среды. Для систем POSIX хорошей стартовой точкой будет список стандартных переменных среды Ubuntu ( https://help.ubuntu.com/community/EnvironmentVariables) или список переменных среды в спецификации POSIX ( http://bit.ly/posix-env-variables), который указывает на другие важные списки.
HowDoI в основном следует PEP 8, но не в тех случаях, когда это вредит читаемости. Например, операторы импорта находятся в верхней части файла, но стандартная библиотека и внешние модули перемешаны. И несмотря на то что строковые константы в USER_AGENTS гораздо длиннее 80 символов, в строках нет места, где их можно было бы разбить естественным образом, поэтому они остаются целыми.
В нескольких следующих фрагментах кода показываются другие решения, связанные со стилем, о которых мы говорили в главе 4.
Имена функций, которые начинаются с нижнего подчеркивания (мы все — ответственные пользователи)
Имя почти каждой функции в HowDoI начинается с нижнего подчеркивания. Это показывает, что функции предназначены лишь для внутреннего использования. Для большинства из них это нужно, потому что при их прямом вызове появляется вероятность генерации необработанного исключения (этим грешат все функции, которые вызывают функцию _get_result()), до тех пор пока не будет вызвана функция howdoi(), обрабатывающая все возможные исключения.
Остальные внутренние функции (_format_output(), _is_question(), _enable_cache() и _clear_cache()) не предназначены для использования за пределами пакета. Тестирующий сценарий howdoi/test_howdoi.py вызывает только функции без префиксов, проверяя, что средство форматирования работает, и передавая аргумент командной строки для раскрашивания в функцию верхнего уровня howdoi.howdoi() вместо того, чтобы передавать код в функцию howdoi._format_output().
Обрабатывайте вопросы совместимости только в одном месте (читаемость имеет значение)
Разница между версиями возможных зависимостей обрабатывается перед выполнением основного кода, поэтому пользователь знает, что проблем с зависимостями не возникнет, а проверка версий не засоряет код в других местах. Это хорошо, поскольку HowDoI поставляется как инструмент командной строки и дополнительные усилия, затрачиваемые пользователями, будут означать, что им не потребуется менять свою среду Python, чтобы установить инструмент. Рассмотрим фрагмент кода, в котором решается эта проблема:
try:
····from urllib.parse import quote as url_quote
except ImportError:
····from urllib import quote as url_quote
try:
····from urllib import getproxies
except ImportError:
····from urllib.request import getproxies
В следующем сниппете разница подходов к обработке Unicode в Python 2 и Python 3 нивелируется всего за семь строк путем создания функции u(x), которая либо эмулирует Python 3, либо не делает ничего. Кроме того, он следует новым принципам цитирования Stack Overflow ( http://meta.stackexchange.com/questions/271080), приводя оригинальный исходный код:
# Разрешаем разницу обработки Unicode между Python 2 и 3
# http://stackoverflow.com/a/6633040/3 05414
if sys.version < '3':
····import codecs
····def u(x):
········return codecs.unicode_escape_decode(x)[0]
else:
····def u(x):
········return x Питонские решения (красивое лучше, чем уродливое)
В следующем фрагменте кода из файла howdoi.py показываются продуманные, питонские решения. Функция get_link_at_pos() возвращает значение False, если результаты не найдены, или определяет ссылки на вопросы, касающиеся Stack Overflow, и возвращает ту из них, которая находится на желаемой позиции (либо последнюю, если ссылок недостаточно).
Функция _is_question() определяется в отдельной строке, что указывает четкое значение непонятному в противном случае поиску с использованием регулярных выражений.
Читать дальше