В чем именно заключается Дзен Python?

Оглавление

Если вы изучаете Python достаточно долго, то, скорее всего, видели или слышали о Дзене Python. Опытные специалисты по Питону часто ссылаются на него как на источник мудрости и руководства, особенно когда хотят разрешить спор по поводу определенных дизайнерских решений в каком-либо фрагменте кода. Другие относятся к этим принципам еще более серьезно, рассматривая их как своего рода питоновский декалог.

В этом уроке вы узнаете, где найти Дзен в Python, как он появился на свет и как интерпретировать его загадочные афоризмы. Вам не нужно быть мастером Python, чтобы понять Дзен в Python! Но вам нужно ответить на важный вопрос: В чем именно заключается Дзен Python?

Короче говоря, Это юмористическое стихотворение, в котором излагается философия Python

Согласно Глоссарию Python, который содержит определения популярных терминов, относящихся к этому языку программирования, Дзен Python - это:

Список принципов проектирования и философии Python, которые полезны для понимания и использования языка. Список можно найти, набрав “import this” в интерактивной подсказке. (Источник)

Действительно, когда вы введете указанную инструкцию import в интерактивный Python REPL, вы получите представлены девятнадцать афоризмов, составляющих дзен Python:

>>> 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, а также внес много других вкладов.

Не торопитесь, ознакомьтесь с "Дзен Питона" и поразмышляйте над его мудростью. Но не воспринимайте афоризмы буквально, поскольку они скорее представляют собой набор руководящих принципов, чем строгие инструкции. В следующем разделе вы узнаете об их юмористическом происхождении.

Как возник Дзен в Python?

Идея разработки единого документа, который бы инкапсулировал фундаментальную философию Python, возникла у основных разработчиков в июне 1999 года. По мере того как все больше и больше людей начинали переходить на Python с других языков программирования, они часто привносили свои предвзятые представления о разработке программного обеспечения, которые не обязательно были питоновскими. Чтобы помочь им следовать духу языка, был необходим набор рекомендаций по написанию идиоматических выражений на Python.

Первоначальное обсуждение создания такого документа состоялось в списке рассылки Python в теме Путь Python. Сегодня вы можете найти этот разговор в официальном архиве Python-list. Если вы внимательно посмотрите на первое сообщение от Тима Питерса в этой теме, то вы заметите, что он в шутку четко описал Дзен Python. Эта первоначальная форма сохранилась и по сей день:

Очевидно, что это работа только для Гвидо, хотя я сомневаюсь, что он возьмется за нее (фууу, я бы тоже этого хотел!). Хотя, вот схема, с которой он бы начал, - подмигнул-:

Красивое лучше уродливого.
Явный вариант лучше, чем неявный.
Простое лучше сложного.
Сложное лучше сложного.
Плоское лучше вложенного.
Разреженное лучше плотного.
Важна читабельность.
Особые случаи не настолько особенные, чтобы нарушать правила.
Хотя практичность превосходит чистоту.
Ошибки никогда не должны проходить незаметно.
Если только они явно не замалчиваются.
Столкнувшись с двусмысленностью, откажитесь от искушения угадать.
Должен быть один – и желательно, только один – очевидный способ сделать это.
Хотя на первый взгляд этот способ может показаться неочевидным, если только вы не голландец.
Сейчас лучше, чем никогда.
Хотя "никогда" часто лучше, чем "прямо сейчас".
Если реализацию трудно объяснить, это плохая идея.
Если реализацию легко объяснить, это может быть хорошей идеей.
Пространства имен – отличная идея, давайте будем использовать их чаще!

Вот и все: 20 питонических тезисов на носу, считая тот, который я оставляю для заполнения Гвидо. Если ответ на любую проблему с дизайном Python не очевиден после их прочтения – что ж, я просто отказываюсь от этого <подмигиваю>. ( Источник)

Подмигивание и игривый способ самоцензуры некоторых сортирных шуток явно указывают на то, что Тим Питерс не хотел, чтобы кто-то воспринял его комментарий слишком серьезно.

Примечание: На случай, если вы не поняли шутку, он начал писать что-то вроде Кал, но затем использовал ^H—который представляет собой Пробел в старых текстовых редакторах, таких как Vim—чтобы удалить последние три буквы и создать слово Тезисы. Таким образом, предполагаемая фраза - это 20 питонических тезисов.

В конце концов, эти почти двадцать тезисов получили собственное название и были официально закреплены в документе Предложение по улучшению Python. Каждый документ PEP получает свой номер. Например, вы, возможно, наткнулись на PEP 8, который является руководством по стилю написания удобочитаемого кода на Python. Возможно, в качестве внутренней шутки, "Дзен Питона" получил номер PEP 20, чтобы обозначить неполное количество афоризмов в нем.

Чтобы выиграть ваш следующий спор о том, что делает код на Python хорошим, вы можете подкрепить свои утверждения "Дзен Питона". Если вы хотите обратиться к конкретному афоризму, а не ко всему стихотворению, рассмотрите возможность посещения страницы pep20.org , где представлены удобные интерактивные ссылки на каждый принцип.

А на случай, если вы захотите выучить стихотворение наизусть и при этом повеселиться, теперь вы можете послушать песню , в которой в качестве текста используется Zen of Python. Барри Уоршоу, еще один разработчик core, работающий с Python с первых дней его существования, сочинил и исполнил эту музыкальную версию. Песня стала заключительным треком на специальной виниловой пластинке под названием The Zen Side of the Moon,, которая была продана с аукциона на PyCon в США. 2023.

Хорошо. Теперь, когда у вас есть приблизительное представление о том, что такое Дзен в Python и как он появился, вы, возможно, задаетесь вопросом, действительно ли вам следует ему следовать.

Должны ли вы соблюдать Дзен Python?

В качестве ироничного комментария, оставленного в списке рассылки, к Zen of Python следует отнестись со всей серьезностью. Как бы то ни было, это набор разумных рекомендаций, которым следуют многие разработчики Python. Они утверждают, что "Дзен" Python способствует созданию элегантного, удобочитаемого и идиоматичного кода, соответствующего философии языка.

В конечном счете, стоит ли вам следовать принципам Python и в какой степени, зависит от вас, поскольку рекомендации открыты для интерпретации. Простое следование им волшебным образом не сделает ваш код похожим на Python или не поможет вам принять обоснованное дизайнерское решение, которое может зависеть от варианта использования. Напротив, субъективные и часто кажущиеся противоречивыми советы, которые дает "Дзен Питона", могут привести вас в еще большее замешательство, чем раньше.

Возьмем в качестве примера самый первый принцип:

Красивое лучше уродливого.

Что именно означает красивый или уродливый? Как вы могли бы оценить, насколько красивым является данный фрагмент кода? В конце концов, один разработчик может не согласиться с интерпретацией красоты другим.

Эти два других принципа, по-видимому, противоречат друг другу:

Особые случаи не настолько особенные, чтобы нарушать правила.
Хотя практичность превосходит чистоту.

Согласно первому принципу, от вас ожидают, что вы всегда будете придерживаться правил, не нарушая их. Но сразу после этого следующий принцип предполагает, что вам следует учитывать практичность решения, даже если иногда это все равно означает нарушение правил. Следовательно, применять Дзен Python, не нарушая хотя бы некоторых из его принципов, практически невозможно. Вы должны выбирать между теми, которым следует следовать, и теми, которые следует обойти или игнорировать.

Крис Нойгебауэр выступил с актуальным докладом о дзене Python и его ограничениях на PyCascades 2023, который вы можете смотреть онлайн. Он исследует декораторов и подсказки по набору текста как два основных примера дизайнерских решений Python, которые не совсем соответствуют дзен-культуре Python.

Декораторы могут помочь вам сосредоточиться на высокоуровневой цели кода, скрывая неинтересные детали реализации за счет того, что делают код более неявным. Это соответствует принципу удобочитаемости, но не в пользу явного кода. С другой стороны, подсказка типа устраняет неявное поведение, добавляя сложности, что противоречит основному принципу Python - делать упор на простоту.

Обратите внимание, что одна и та же функция может одновременно соответствовать принципам Python и не соответствовать им, в зависимости от того, под каким углом вы на это смотрите. Во многих случаях вам нужно будет найти баланс и решить, что наиболее целесообразно для вашего проекта.

В заключение, хотя "Дзен Питона" содержит полезные рекомендации, вам не следует строго придерживаться его как набора правил, высеченных на камне. Вместо этого вам следует отдавать предпочтение практичности и адаптировать свой подход к конкретной проблеме. Принимая решение о том, следует ли придерживаться этих общепринятых рекомендаций, учитывайте другие факторы, такие как производительность, бизнес-требования и командные договоренности.

Как Вы можете интерпретировать некоторые из этих афоризмов?

"Дзен Python" состоит из девятнадцати афоризмов, некоторые из которых отдают предпочтение одной конкретной черте, а не другой, высказывая мнение о том, что делает ваш код лучше :

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!

В этом разделе вы более подробно ознакомитесь с этими рекомендациями, попытавшись дать им разумное толкование.

Первый принцип "Дзен Питона" гласит, что:

Красивое лучше уродливого.

Хотя красота в глазах смотрящего, нельзя отрицать, что одним из факторов популярности Python, особенно в сообществе data science, является его доступный и эстетически приятный синтаксис. Рассмотрим следующую функцию, которая создает синусоидальную волну с заданной амплитудой, угловой частотой и фазовым сдвигом:

from math import sin

def sinusoid(A, ω, ϕ):
    return lambda t: A * sin(ω * t + ϕ)


Этот код читается почти как математическая формула благодаря компактному синтаксису Python, который вам не мешает. Использование греческих букв в названиях переменных, столь часто встречающихся в уравнениях такого типа, мгновенно делает код понятным любому, кто знаком с лежащей в его основе теорией. Наконец, лямбда-выражение делает код кратким, сохраняя при этом удобочитаемость. Как вы можете видеть, ясность 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.

Следующие два принципа из "Дзен Питона" таковы:

Простое лучше сложного.
Сложное лучше сложного.

Самые простые решения часто оказываются самыми элегантными и эффективными. Эта истина известна со времен Ренессанса, поскольку знаменитое высказывание “простота - это предел изысканности” часто приписывают Леонардо да Винчи.

Однако простота не всегда возможна, поскольку некоторые системы сложны по своей природе и состоят из множества движущихся частей и слоев. Но это не значит, что они должны быть сложными или труднопонимаемыми. Часто вы можете разбить более крупную проблему на более мелкие и более управляемые подзадачи. 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 - отличный инструмент для создания прототипов! Вы всегда можете продолжать работу над своим решением, не попадая в ловушку преждевременной оптимизации, которую Дональд Кнут назвал “корнем всех зол” в информатике.

В то же время вам не следует принимать решения слишком поспешно, бросаясь к их реализации, не задумываясь об этом хотя бы немного. Терпение может избавить вас от необходимости тратить свое время и усилия на то, что не принесет желаемых результатов. Ваша интуиция может вас подводить, поэтому нет смысла работать над чем-то, что вам в первую очередь не понадобится.

Как вы можете догадаться, овладение дзен-языком Python означает тщательное обдумывание каждого совета, даже если афоризмы могут показаться противоречивыми. Хотя изучение каждой строки выходит за рамки данного руководства, чем больше вы работаете с Python, тем более интуитивно понятными становятся эти пословицы.

Какие скрытые шутки скрывает Дзен Python?

Хотя знакомство с Python началось с шутки, юмор на этом не заканчивается. Python известен множеством остроумных отсылок, разбросанных по всему языку. В конце концов, само его название является данью уважения комедийной группе "Монти Пайтон", а официальная документация полна каламбуров, которые ссылаются на их многочисленные скетчи. Например, spam является распространенным именем-заполнителем, используемым вместо более традиционного foobar как неофициальный намек на Спам-скетч.

Интересный факт: Современное значение спама как нежелательной цифровой коммуникации также вытекает из классического скетча Монти Пайтона, в котором чрезмерно повторяется слово "спам". .

Есть забавная история о фразе импортируйте это, которую Барри Уоршоу задокументировал в своем блоге. В двух словах, эта фраза была выбрана из сотен предложений сообщества для слогана, который можно было бы напечатать на футболке для конференции по Python в 2001 году. В самый последний момент Барри пришла в голову идея реализовать this.py и внедрить его в следующий выпуск Python, никому не сказав об этом. При импорте модуль продемонстрировал бы преимущества Python.

Чтобы усложнить поиск информации о Python в исходном коде Python, Барри и его небольшая группа сообщников добавили модуль с отключенными уведомлениями. Они держали это при себе и даже зашли так далеко, что запутали код, используя шифр подстановки ROT-13, чтобы скрыть свое секретное сообщение. Только намного позже кто-то, наконец, обнаружил спрятанный модуль.

Примечание: Отображение Дзена Python после импорта this - это всего лишь одно из многих пасхалок, тайно ввезенных в Питон, но есть еще несколько яиц, ожидающих своего обнаружения. Вы можете начать работу, загрузив следующее руководство:

Бесплатный бонус: Нажмите здесь, чтобы загрузить программу Easter egg hunt и узнать, что скрывается внутри Python!

Нашли ли вы других? Поделитесь ими в комментариях ниже!

По иронии судьбы, когда вы более внимательно посмотрите на this.py в исходном коде Python, вы сразу заметите, что это нарушает многие из принципов Дзен самого 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 вместо ручной реализации алгоритма с вложенными циклами, которые не являются плоскими.

Прямо перед вашими глазами прячется еще одно пасхальное яйцо. Один из принципов "Дзен Питона" - это шутливая отсылка к Гвидо ван Россуму, создателю Python, который родом из Нидерландов:

Хотя поначалу этот способ может показаться неочевидным, если только вы не голландец.

Гвидо также известен как Пожизненный доброжелательный диктатор (BDFL) Python, пользующийся большим уважением и оказывающий влияние на язык и его эволюцию. В 2018 году он официально ушел с этой должности, но остается ключевой фигурой в сообществе Python.

У автора Zen of Python отличное чувство юмора. Давным-давно кто-то открыл тикет в старом баг-трекере Python, чтобы указать на пунктуационную ошибку в другом принципе. Ошибка заключается в непоследовательном использовании тире em () в следующем предложении:

Должен быть один – и желательно только один – очевидный способ сделать это.

Однако эта ошибка была преднамеренной! Шутка, как объяснил сам Тим Питерс, заключается в том, что существуют разногласия по поводу того, следует ли использовать пробелы вокруг тире или нет:

Боюсь, вы пропустили шутку ;-) Хотя вы и считаете, что пробелы требуются с обеих сторон от тире, единого мнения по этому поводу нет. Например, большинство (но не все) Американские власти запрещают использовать пробелы. В этом и заключается шутка. При написании строки о “только одном способе сделать это” я использовал устройство (em dash), для которого обычно используются по крайней мере два способа сделать это (с пробелами и без пробелов), ни один из которых не очевиден, и намеренно выбрал третий способ, просто чтобы подчеркнуть это.

Это никогда не изменится ;-) (Источник)

Кроме того, этот афоризм непосредственно адресован программистам на Perl, чьим девизом было “есть более чем один способ сделать это,”часто сокращается до ТИМТОУТДИ и произносится как Тим Тоуди. В 1990-х и начале 2000-х Perl и Python были жесткими конкурентами, и в их сообществах царило дружеское соперничество. На самом деле "Дзен Python" был создан как тонкий способ подшутить над Perl.

Итак, вот и все. Двадцать принципов Дзен, из которых только девятнадцать были записаны, полны остроумных шуток и ссылок, которые по достоинству оценит только истинный знаток языка. Теперь ты можешь считать себя одним из них!

Заключение

В этом уроке вы познакомитесь с "Дзен Python" - юмористическим стихотворением Тима Питерса, в котором излагаются философские взгляды на Python. Попутно вы узнаете, как она возникла, что означают некоторые из ее афоризмов и стоит ли вам следовать им.

Вы также обнаружили несколько внутренних шуток и отсылок, скрытых в "Дзен Питона", который в настоящее время является важной частью культуры Python. Теперь, когда вы знаете историю, стоящую за этим, почему бы вам не уделить несколько минут и не прочитать "Дзен Питона" еще раз, чтобы оценить его истинный блеск?

Back to Top