Zen of Python
Если вы имеете отношение к Питону, то вот небольшой совет. Никогда не упоминайте знаменитый Zen of Python: ни в шутку, ни всерьез. Если упоминает кто-то другой, пропускайте мимо ушей, не важно насколько он именит.
Объяснение этому следующее. Современный Питон бесконечно далек от тезисов Zen of Python. Я заметил это пятнадцать лет назад, когда писал на Python 2.5. Тогда я не мог высказаться, но время пришло.
Я не говорю, что это плохо. Наоборот, Питон — одна из лучших вещей в айти (иногда мне кажется, что слишком хорошая). Питон — первый язык, ориентированный на пользователя. Отсюда такая любовь и популярность.
Расхождение с Zen of Python было неминуемым, потому что язык развивался. Полагаю, Zen of Python был актуален несколько первых версий, а потом устарел — не быть же языку заложником старых догм. Это совершенно нормально.
Поэтому я рассматриваю Zen of Python как исторический документ. Подкреплять им свои доводы в спорах несерьезно. С таким же успехом можно ссылаться на скрижали Майя или гороскоп.
Половина доводов в Zen of Python не имеет смысла, а вторая потеряла актуальность. Я не буду дотошно перечислять каждый пункт: повторюсь, половина из них бессмысленна. Я не знаю, как комментировать “красивое лучше, чем уродливое” — с таким же успехом можно сказать, что котики лучше пьяной драки. Зато знаю, какие пункты прямо нарушают то, что в Питоне, и сейчас вам о них расскажу.
Один из тезисов звучит примерно как “должен быть один способ сделать что-то”:
There should be one– and preferably only one –obvious way to do it
Когда я слышу это утверждение, то могу только фыркнуть. В Питоне бесконечное число способов что-то сделать. Из-за своей гибкости и многолетнего контриба одну и ту же задачу можно выполнить разными способами. При этом число способов со временем только множится.
Простой пример — в Питоне три способа форматирования строк: старый сишный с
процентом, джавный string.format()
и f-строки, которые по сути eval. Я обожаю
троллить питонистов форматированием с процентом. Если вы возьмете меня в проект
на Питоне, я обязательно напишу так:
return "<%s %s>" % (user_name, user_email, )
Не потому что я упорот, а чтобы проверить вашу реакцию. Происходит следующее: коллега читает код и подвисает на этой строчке. Его уже не волнует бизнес-логика и покрытие тестов. В нем зреет тревога: всем известно, что нужно пользоваться f-строками, а тут какой-то синтаксис времен Unix… Подключается второй питонист, слово за слово, и начинается срач — как правильно форматировать строки. Плывут экраны комментариев, я сижу и улыбаюсь.
Библиотеки с говорящими именами httplib
и httplib2
, а также urllib
,
urllib2
и urllib3
(последняя — сторонняя). Все они страшные, и нормальную
открывашку урлов сделали только в requests
.
У словаря есть метод update
. Добавили оператор |=
(палка-равно), который
делает то же самое. Господи, зачем? Может, добавите еще |>
, |~
, |-
и
другие? Удобней и короче, чем .update
, .intersect
и прочие английские слова.
С каждый релизом в Питоне все больше трюков, библиотек и операторов. Забавно,
когда одна строчка from __future__ import foo
расширяет синтаксис или даже
интерпретатор.
Словом, тезис о том, что должен быть один способ что-то сделать, совершенно неактуален.
Другие тезисы Zen of Python вроде как поощряют простые решения:
Explicit is better than implicit. Simple is better than complex. Flat is better than nested.
Давайте откроем исходники Django Framework, а именно его сердце — модели. Потому что в Django все вращается вокруг моделей — пользователи, данные, админка — и без моделей он никому не нужен.
Смотрим класс ModelBase
, метод __new__()
: семь экранов магии. Здесь и
махинации с атрибутами, и прокси-классами, и наследование, и то, и се вперемешку
с многими if-else. Найдется ли питонист, который внятно объяснит, что там
происходит?
Но ModelBase
— это всего лишь метакласс класса Model
, в котором похожая
петрушка. В методе __init__
четыре экрана кода с разными манипуляциями с
аргументами. И этот код со всей своей магией постоянно крутится у тех, кто ведет
проекты на Django.
Ничуть не лучше ситуация с формами и виджетами. Там тоже метаклассы с махинациями, которые простым смертным не понять.
Я веду к следующему: чтобы сделать удобно потребителю, код может быть чудовищно сложным. Но потребитель об этом не знает: он вызывает методы и рассказывает догмы из Zen of Python, что simple is better than complex. То, что внутри экраны магии с метаклассами, его не интересует.
Другой довод в пользу того, что в Питоне не приживаются простые решения, следующей. Если бы это было так, то проекты на Питоне строили бы на списках, словарях и функциях. А на практике любой проект на Питоне — как Джава: классы, классы, классы. Гигантский граф изменяемых объектов.
Еще один пункт из Zen of Python говорит про неймспейсы:
Namespaces are one honking great idea – let’s do more of those!
Если кто-то знает о пространствах имен в Питоне, пожалуйста, сообщите мне, потому что за 10 лет я о них ничего не узнал. В Питоне обычная система модулей, которые импортируются друг в друга. Никаких особых свойств у модулей нет.
Для сравнения: в известном скобочном языке символы и кейворды могут быть
привязаны неймспейсу. Символ foo
из неймспейса com.test
не равен символу
foo
из bar.test
. Такая связь пространства имен и символов/кейвордов
открывает полезные техники, о которых я не буду сейчас, потому что это другой
язык. В Питоне ничего подобного нет, и к чему тезис о неймспейсах, непонятно.
Повторюсь, бессмысленность Zen of Python не имеет отношения к языку. Можно писать на нем отличный код, даже не зная о Дзене. Но доказывать точку зрения, опираясь на тезисы Zen of Python — вот образец бессмысленности.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter
Александр, 29th Jul 2024, link
А что думаете про “Explicit is better than implicit.”? Всегда явное лучше? Если рассматривать не только питон
Ivav Grishaev, 30th Jul 2024, link
Хорошее замечание, надо было добавитьв статью. Я лично не вижу, чтобы этот тезси соблюдался. В притоне приняты удобные, а не простые решения. А удобные, как правило, полны магии.