Команда Python for Devs подготовила перевод статьи о Zen of Python — шуточном, но глубоком своде афоризмов, которые уже четверть века задают тон питонячей культуре. Как появился этот «питонячий декалог», зачем он нужен и стоит ли ему следовать?
Если вы достаточно давно изучаете Python, то наверняка уже сталкивались с понятием Zen of Python. Опытные питонисты часто ссылаются на него как на источник мудрости и ориентир, особенно когда нужно разрешить спор о том или ином решении в коде. Некоторые относятся к этим принципам ещё серьёзнее, воспринимая их как своеобразный «питонический декалог».
В этой статье вы узнаете, где можно найти Zen of Python, как он появился и как понимать его загадочные афоризмы. Чтобы разобраться в Zen of Python, не нужно быть мастером языка! Но один важный вопрос вам всё же предстоит задать: что же такое Zen of Python?
TL;DR: это шутливое стихотворение, перечисляющее принципы Python
Согласно глоссарию Python, который содержит определения распространенных терминов, связанных с этим языком, Zen of Python — это:
Список принципов проектирования и философии Python, которые помогают понимать и использовать язык. Этот список можно вывести, набрав в интерактивной оболочке «import this». (Источник)
И действительно, если набрать указанный оператор импорта в интерактивном REPL Python, вы увидите девятнадцать афоризмов, составляющих Zen of Python:
>>> import this
The Zen of Python, by Tim Peters
Красивое лучше, чем уродливое.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложное лучше, чем запутанное.
Плоское лучше, чем вложенное.
Разреженное лучше, чем плотное.
Читаемость имеет значение.
Частные случаи недостаточно особенные, чтобы нарушать правила.
Хотя практичность важнее чистоты.
Ошибки не должны проходить незамеченными.
Если их не заглушили явно.
Столкнувшись с неоднозначностью, отвергайте соблазн угадывать.
Должен существовать один — и, желательно, только один — очевидный способ сделать это.
Хотя этот способ может быть неочевиден сначала — если только вы не голландец.
Сейчас лучше, чем никогда.
Хотя «никогда» часто лучше, чем прямо сейчас.
Если реализацию трудно объяснить — это плохая идея.
Если реализацию легко объяснить — возможно, это хорошая идея.
Пространства имен — чертовски отличная идея — давайте использовать их чаще!
Оригинал
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Подпись раскрывает автора стихотворения — Тима Питерса, известного инженера-программиста и давнего участника CPython, прославившегося созданием алгоритма сортировки Timsort. Он также автор модулей doctest и timeit в стандартной библиотеке Python и многих других вкладов.
Найдите время, чтобы внимательно прочитать Zen of Python и поразмышлять над его мудростью. Но не понимайте афоризмы буквально: это скорее набор ориентиров, чем строгие инструкции. О том, какова их шутливая природа, вы узнаете в следующем разделе.
Как появился Zen of Python?
Идея создать единый документ, который объединил бы фундаментальные принципы Python, возникла среди разработчиков ядра в июне 1999 года. Всё больше людей приходило в Python из других языков программирования, и вместе с ними — их представления о том, каким должно быть проектирование программ. Эти взгляды не всегда соответствовали духу Python. Чтобы помочь новичкам следовать «питонячному пути», потребовался набор рекомендаций для написания идиоматичного кода.
Первое обсуждение создания такого документа прошло в рассылке Python под темой The Python Way. Сегодня эту переписку можно найти в официальном архиве Python-list. Если внимательно прочитать первое сообщение Тима Питерса в том треде, то станет ясно: Zen of Python он изначально сформулировал в шутливой форме. И именно в таком виде он сохранился до наших дней:
Очевидно, что это задача исключительно для Гвидо — хотя сомневаюсь, что он возьмётся за неё (честно говоря, я бы этого тоже хотел!). Вот, с чего бы он начал <подмигивает>:
Красивое лучше, чем уродливое. Явное лучше, чем неявное. Простое лучше, чем сложное. Сложное лучше, чем запутанное. Плоское лучше, чем вложенное. Разреженное лучше, чем плотное. Читаемость имеет значение. Частные случаи недостаточно особенные, чтобы нарушать правила. Хотя практичность важнее чистоты. Ошибки не должны проходить незамеченными. Если их не заглушили явно. Столкнувшись с неоднозначностью, отвергайте соблазн угадывать. Должен существовать один — и, желательно, только один — очевидный способ сделать это. Хотя этот способ может быть неочевиден сначала — если только вы не голландец. Сейчас лучше, чем никогда. Хотя «никогда» часто лучше, чем прямо сейчас. Если реализацию трудно объяснить — это плохая идея. Если реализацию легко объяснить — возможно, это хорошая идея. Пространства имен — чертовски отличная идея — давайте использовать их чаще!
Вот вам: 20 питонячных тезисов (в оригинале: Fec^H^H^HTheses), включая один, который я оставляю на заполнение Гвидо. Если после их прочтения ответ на какой-то вопрос о дизайне Python остаётся неочевидным — что ж, я сдаюсь <подмигивает>. (Источник)
Подмигивание и игривое самоцензурирование «туалетного юмора» ясно показывают, что Тим Питерс вовсе не ожидал, что его комментарий будут воспринимать слишком серьёзно.
Примечание: если шутка осталась непонятной, он начал писать слово Feces, но затем использовал символ
^H
— в старых текстовых редакторах вроде Vim он обозначал клавишу Backspace — чтобы удалить три последние буквы и заменить слово на Theses. То есть подразумевалась фраза 20 Pythonic Theses («20 питонических тезисов»).
Со временем эти почти два десятка тезисов получили собственное название и были официально закреплены в документе PEP (Python Enhancement Proposal). Каждый PEP получает свой номер. Например, вы, возможно, встречали PEP 8 — руководство по стилю для написания читаемого кода на Python. А Zen of Python, видимо в качестве шутки, достался номер PEP 20 — в честь «незавершённого» числа афоризмов.
Теперь, если вам нужно выиграть спор о том, каким должен быть правильный питонячий код, вы можете смело ссылаться на Zen of Python. А если хочется сослаться на конкретный афоризм, а не на всё стихотворение целиком, загляните на pep20.org — там каждый принцип удобно вынесен в отдельную ссылку.
И если вдруг захочется выучить стихотворение наизусть в более весёлой форме, можно послушать песню, где текстом выступает Zen of Python. Её написал и исполнил Барри Варшав, ещё один давний участник разработки Python. Композиция стала финальным треком на виниловой пластинке The Zen Side of the Moon, которую выставили на аукционе во время PyCon US 2023.
Ну что ж. Теперь, когда у вас есть общее представление о том, что такое Zen of Python и как он появился, самое время задаться вопросом: а стоит ли на самом деле ему следовать?
Стоит ли следовать Zen of Python?
Поскольку Zen of Python появился как шуточный комментарий в рассылке, относиться к нему стоит с долей иронии. Тем не менее, это набор вполне разумных рекомендаций, которым многие разработчики Python действительно следуют. Они утверждают, что Zen of Python способствует написанию элегантного, читаемого и идиоматичного кода, соответствующего духу языка.
В конечном счёте, решение о том, нужно ли придерживаться Zen of Python и в какой степени, остаётся за вами, ведь его принципы открыты для интерпретации. Слепое следование афоризмам не сделает ваш код автоматически «питонячим» и не поможет принять верное архитектурное решение, которое зачастую зависит от конкретной задачи. Напротив, субъективные и порой противоречивые советы из Zen of Python могут запутать ещё сильнее.
Возьмём, к примеру, самый первый принцип:
Красивое лучше, чем уродливое.
Но что именно значит «красивое» или «уродливое»? Как измерить красоту кода? Ведь один разработчик может совершенно не согласиться с интерпретацией другого.
А вот два других принципа, которые, кажется, противоречат друг другу:
Частные случаи недостаточно особенные, чтобы нарушать правила. Хотя практичность важнее чистоты.
Первый призывает никогда не нарушать правила, а второй тут же намекает, что ради практичности иногда можно сделать исключение. Поэтому применять Zen of Python так, чтобы не нарушить хотя бы некоторые его принципы, практически невозможно. Вам придётся выбирать: каким из них следовать строго, а какие — при необходимости интерпретировать иначе или вовсе игнорировать.
Крис Нойгебауэр прочитал интересный доклад о Zen of Python и его ограничениях на конференции PyCascades 2023, запись которого доступна онлайн. В нём он рассматривает декораторы и аннотации типов как два показательных примера решений в Python, которые не вполне соответствуют принципам Zen of Python.
Декораторы помогают сосредоточиться на основной логике кода, скрывая второстепенные детали реализации. Это повышает читаемость, но при этом делает код менее явным, что нарушает другой принцип. Аннотации типов, напротив, устраняют неявность, но вносят дополнительную сложность, что противоречит стремлению к простоте.
Таким образом, одна и та же возможность языка может одновременно соответствовать Zen of Python и противоречить ему — всё зависит от угла зрения. Во многих случаях приходится искать баланс и решать, что именно будет оптимальным для конкретного проекта.
Подводя итог: Zen of Python действительно даёт полезные ориентиры, но относиться к нему как к своду высеченных в камне правил не стоит. Гораздо важнее учитывать практичность и адаптировать подход к конкретной задаче. При этом не забывайте о таких факторах, как производительность, бизнес-требования и правила команды, принимая решение о том, насколько строго следовать этим субъективным принципам.
Как можно трактовать некоторые афоризмы?
Zen of Python состоит из девятна��цати афоризмов, часть из которых противопоставляют одни качества другим, выражая мнение о том, что делает код лучше:
Красивое лучше, чем уродливое.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложное лучше, чем запутанное.
Плоское лучше, чем вложенное.
Разреженное лучше, чем плотное.
***
Сейчас лучше, чем никогда.
Хотя «никогда» часто лучше, чем прямо сейчас.
***
В этом разделе мы подробнее рассмотрим некоторые из этих принципов и попытаемся дать им разумное толкование.
Первый афоризм Zen of Python гласит:
Красивое лучше, чем уродливое.
Хотя красота — понятие субъективное, нельзя отрицать, что одной из причин популярности Python, особенно в сообществе специалистов по анализу данных, стала его понятная и эстетичная синтаксическая форма. Рассмотрим, например, такую функцию, создающую синусоиду с заданной амплитудой, угловой частотой и фазовым сдвигом:
from math import sin
def sinusoid(A, ω, ϕ):
return lambda t: A * sin(ω * t + ϕ)
Этот код почти дословно повторяет математическую формулу благодаря лаконичному синтаксису Python, который не мешает выражать суть. Использование греческих букв в названиях переменных — привычная практика для подобных уравнений — делает код понятным каждому, кто знаком с теорией. Наконец, лямбда-выражение делает реализацию компактной, сохраняя при этом читаемость. Как видите, ясность и выразительность Python сложно превзойти.
Второй принцип Zen of Python звучит так:
Явное лучше, чем неявное.
Этот афоризм подчёркивает важность того, чтобы код был максимально понятным и прозрачным, а не полагался на неоговорённые допущения или скрытые правила. Например, при определении функции гораздо лучше явно указывать ожидаемые типы параметров и возвращаемого значения, чем заставлять читающего гадать:
from math import sin
from typing import Callable, TypeAlias
Amplitude: TypeAlias = float
AngularFrequency: TypeAlias = float
PhaseShift: TypeAlias = float
Time: TypeAlias = float
SineWave: TypeAlias = Callable[[Time], float]
def sinusoid(A: Amplitude, ω: AngularFrequency, ϕ: PhaseShift) -> SineWave:
"""Return a function that computes the sine wave at a given time."""
return lambda t: A * sin(ω * t + ϕ)
Здесь заданы несколько псевдонимов типов с понятными именами, и они использованы в подсказках типов для параметров функции, что сразу раскрывает их назначение и область применения. Дополнительно добавлена строка документации, поясняющая, что именно возвращает функция. Теперь любой, кто посмотрит на этот код, легко поймёт, что он делает и как им пользоваться.
Примечание: если вы раньше не встречали подсказки типов в Python, то двоеточие (:) в приведённом коде отделяет имена переменных от их типов. Иными словами, запись A: Amplitude означает, что параметр A должен иметь тип Amplitude, а Amplitude: TypeAlias говорит о том, что Amplitude — это псевдоним для другого типа, в данном случае float.
Следующие два принципа Zen of Python звучат так:
Простое лучше, чем сложное. Сложное лучше, чем запутанное.
Самые простые решения часто оказываются и наиболее элегантными, и наиболее эффективными. Эта истина известна со времён Ренессанса: фразу «простота — высшая форма изысканности» часто приписывают Леонардо да Винчи.
Правда, добиться простоты не всегда возможно. Некоторые системы по своей природе сложны: они состоят из множества частей и уровней. Но это не значит, что они должны быть запутанными и трудными для понимания. Большую задачу часто можно разбить на несколько меньших и более управляемых подзадач. Python предлагает для этого богатый набор инструментов — списковые включения, генераторы, итераторы и многое другое.
Ещё одна пара принципов из Zen of Python:
Плоское лучше, чем вложенное. Разреженное лучше, чем плотное.
Когда речь идёт о структуре кода, обычно предпочтительнее избегать глубокой вложенности. В более раннем примере лямбда-выражение заменяло внутреннюю функцию, которая могла бы выглядеть так:
def sinusoid(A: Amplitude, ω: AngularFrequency, ϕ: PhaseShift) -> SineWave:
"""Return a function that computes the sine wave at a given time."""
def wave(t: Time) -> float:
return A * sin(ω * t + ϕ)
return wave
Этот код стал чуть более явным и понятным, но при этом он более вложенный и многословный. Если у вас появится несколько уровней вложенности друг в друга, всё быстро превратится в нагромождение, за которым трудно следить.
С другой стороны, может возникнуть соблазн уместить как можно больше логики в одну строку. Здесь вступает в силу второй принцип. Вместо одной длинной и плотной строки кода обычно лучше разнести отдельные шаги по разным строкам — так их легче осмыслить:
def dense(A, f, ϕ):
return lambda t: A * sin(2 * π * f * t + ϕ)
def sparse(A, f, ϕ):
ω = 2 * π * f
return lambda t: A * sin(ω * t + ϕ)
В этом примере функция sparse()
разбивает длинную формулу на более мелкие части, выделяя независимые выражения в отдельную строку. Да, вертикально строк стало больше, но каждая из них короче и по отдельности читается легче.
Два заключительных принципа, дающих качественные ориентиры:
Сейчас лучше, чем никогда. Хотя «никогда» часто лучше, чем прямо сейчас.
Первый призывает переходить к делу и пробовать реализовать рабочий прототип. К слову, Python отлично подходит для прототипирования! Вы всегда можете продолжать итерации над решением, не попадая в ловушку преждевременной оптимизации, которую Дональд Кнут метко назвал «корнем всего зла» в информатике.
Одновременно с этим не стоит принимать решения слишком поспешно и бросаться в реализацию, не подумав хотя бы немного. Терпение может уберечь вас от траты времени и сил на то, что не даст желаемого результата. Интуиция способна подвести, и нет смысла работать над тем, что в итоге не понадобится.
Как видите, понимать Zen of Python — значит вдумчиво относиться к каждому совету, даже когда афоризмы кажутся противоречивыми. Разбирать их все по строчке — за пределами этого материала, но чем больше вы работаете с Python, тем более естественными и понятными становятся эти изречения.
Какие внутренние шутки скрывает Zen of Python?
Хотя Zen of Python начался как шутка, юмор на этом не заканчивается. Python вообще известен множеством остроумных отсылок, рассыпанных по всему языку. В конце концов, его название — дань комик-группе Monty Python, а официальная документация полна каламбуров и намёков на их скетчи. Например, слово spam часто используется как фиктивное имя вместо привычного foobar — это неформальная отсылка к знаменитому скетчу про Spam.
Забавный факт: современное значение слова spam как нежелательной цифровой рассылки тоже восходит к этому классическому скетчу Monty Python, где слово spam повторяется до навязчивости.
С фразой import this
связана любопытная история, которую Барри Варшав описал у себя в блоге. В двух словах: эту фразу выбрали из сотен предложений сообщества как слоган для футболки на конференции Python в 2001 году. В самый последний момент Барри пришла идея действительно реализовать файл this.py
и тайком пронести его в следующий релиз Python, никому об этом не сказав. При импорте модуль должен был показывать Zen of Python.
Чтобы усложнить поиск Zen of Python в исходниках Python, Барри и небольшая группа сообщников добавили модуль с отключёнными уведомлениями. Они держали всё в секрете и даже обфусцировали код с помощью шифра подстановки ROT-13, чтобы скрыть своё сообщение. Лишь много позже кто-то наконец обнаружил этот спрятанный модуль.
Ирония в том, что если присмотреться к this.py
в исходном коде Python, то сразу бросается в глаза: сам он нарушает многие принципы Zen of Python:
s = """Gur Mra bs Clguba, ol Gvz Crgref
Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""
d = {}
for c in (65, 97):
for i in range(26):
d[chr(i+c)] = chr((i+13) % 26 + c)
print("".join([d.get(c, c) for c in s]))
Этот модуль трудно назвать красивым или читаемым: из-за обфускации реализацию сложно объяснить. Кроме того, имена переменных в одну букву не являются явными, а их объявление в глобальной области видимости вовсе игнорирует пространства имён. Наконец, декодировать сообщение можно было проще, воспользовавшись модулем codecs
, вместо ручной реализации алгоритма с вложенными циклами, которые, к тому же, не «плоские».
Есть и ещё одна пасхалка, скрытая прямо у вас перед глазами. Один из принципов Zen of Python — это игривая отсылка к создателю Python, Гвидо ван Россуму, который родом из Нидерландов:
Хотя этот способ может быть неочевиден сначала — если только вы не голландец.
Гвидо также известен как Benevolent Dictator for Life (BDFL) — «добрый диктатор пожизненно». Он пользовался огромным уважением и имел значительное влияние на развитие языка. В 2018 году он официально отошёл от этой роли, но до сих пор остаётся ключевой фигурой сообщества Python.
Автор Zen of Python обладает отличным чувством юмора. Давным-давно кто-то завёл тикет в старом баг-трекере Python, указав на пунктуационную ошибку в другом афоризме. Ошибка заключалась в несогласованном использовании длинных тире (—) в следующем предложении:
Должен существовать один– и, желательно, только один –очевидный способ сделать это.
Однако это было сделано нарочно! Как сам Тим Питерс объяснил, суть шутки в том, что нет единого мнения, нужно ли ставить пробелы вокруг длинного тире или нет:
Боюсь, вы не уловили шутку ;-) Вы полагаете, что пробелы нужны с обеих сторон длинного тире, но консенсуса здесь нет. Например, большинство (но не все) американские справочники утверждают, что пробелы использовать /не/ нужно. В этом и заключается шутка. Когда я писал строчку о том, что «есть только один способ это сделать», я специально использовал символ (длинное тире), у которого как минимум два варианта употребления (с пробелами, без пробелов) встречаются одинаково часто, и ни один из них не является «очевидным». А затем я нарочно выбрал третий способ — чтобы поддразнить.
И это никогда не изменится ;-) (Источник)
Кроме того, данный афоризм напрямую обращён к программистам на Perl, чьим девизом было «there is more than one way to do it» (сокращённо TIMTOWTDI, произносится как Tim Toady). В 1990-е и начале 2000-х Perl и Python были серьёзными конкурентами, а их сообщества вели дружеское соперничество. Zen of Python изначально и создавался как тонкая насмешка над Perl.
Вот так: двадцать принципов Zen, из которых записано только девятнадцать, полны остроумных шуток и отсылок, которые по достоинству оценит лишь настоящий питонист. Теперь вы можете считать себя одним из них!
Русскоязычное сообщество про Python

Друзья! Эту статью перевела команда Python for Devs — канала, где каждый день выходят самые свежие и полезные материалы о Python и его экосистеме. Подписывайтесь, чтобы ничего не пропустить!
Заключение
В этой статье вы познакомились с Zen of Python — шуточным стихотворением с философскими принципами Python, автором которого является Тим Питерс. Вы узнали, как он появился, что означают ��екоторые его афоризмы и стоит ли им следовать.
Мы также разобрали несколько скрытых шуток и отсылок, спрятанных в Zen of Python, который сегодня стал важной частью культуры языка. А теперь, зная его историю, почему бы не перечитать Zen of Python ещё раз — чтобы по-настоящему оценить его изящество?