26 марта 2010 в 08:33

Code Like a Pythonista: Idiomatic Python (part0) перевод

Kaa, the Python
От переводчика:

Я только начал изучать Python. С самого первого знакомства язык порадовал симпатичными конструкциями и синтаксически-гарантированной удобностью к чтению и пониманию кода.
В процессе освоения, при написании своего кода, бывает, сомневаюсь в правильности выбранных способов с точки зрения Python-way ( PEP 8 — Style Guide for Python Code, если угодно). Для вникания в идеологию программирования, в Python-сообществе кроме исчерпывающей документации, ко всеобщей радости, накоплено уже немало вспомогательных материалов, таких как статья Python Tips, Tricks, and Hacks, перевод которой недавно появился на Хабре
Мне понравилась статья Дэвида Гуджера «Пиши код, как настоящий Питонист: идиоматика Python» (David Goodger «Code Like a Pythonista: Idiomatic Python»). Для лучшего её усвоения решил оформить (в силу умения) полноценный перевод, потом показалось здравой идеей поделиться с Хабром.
Пока работал над переводом, пришло понимание, что статья существенно больше, чем показалась при прочтении ее в оригинале, поэтому постить буду частями, чтобы не выпасть из формата Хабра-статьи.
Продолжение и окончание перевода.





Пиши код, как настоящий Питонист: идиоматика Python


David Goodger
goodger@python.org
http://python.net/~goodger

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

Creative Commons
Attribution/Share-Alike (BY-SA) license.
Обо мне:
  • живу в Монреале,
  • отец двоих детей, муж одной женщины
  • Python-программист полный рабочий день (a full-time Python programmer),
  • автор проекта Docutils и reStructuredText,
  • редактор Python Enhancement Proposals (or PEPs),
  • организатор PyCon 2007, и кафедры PyCon 2008,
  • член Python Software Foundation,
  • директор фонда в прошлом году, и секретарь в нынешнем.

Этот туториал я представил на конференции PyCon 2006 (called Text & Data Processing), я был удивлен реакцией на некоторые методы, которые я использовал и считал их общеизвестными. Но многие слушатели были в неведении о методах, которые используются Python-программистами, не задумываясь.
Многие из вас могли видеть некоторые идиомы и методы раньше. Хочется верить, что вы также узнаете несколько приемов, которые не видели раньше и может быть узнаете кое-что новое о тех, что уже вам знакомы.


Дзен Python (1)


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

Красивое лучше безобразного.
Явное лучше неявного.
Простое лучше сложного.
Сложное лучше запутанного.
Плоское лучше вложенного.
Разреженное лучше плотного.
Читаемость важна.
Исключительные случаи не достаточно исключительны, чтобы нарушать правила.
Хотя практичность важнее красоты.
Ошибки не должны проходить молча.
Если не заглушены явно.
...


Дзен Python (2)


При неоднозначности откажитесь от искушения догадаться.
Должен существовать один и, желательно, только один, очевидный, способ сделать это.
Хотя этот путь может оказаться не очевидным сначала, если только вы не из Голландии (видимо имеется ввиду Гвидо ван Россум — прим. перев., спасибо sgtpep).
Сейчас лучше, чем никогда.
Хотя никогда зачастую лучше, чем прямо сейчас.
Если реализацию сложно объяснить, то это плохая идея.
Если реализацию легко объяснить, это, возможно, хорошая идея.
Пространства имен — грандиозная идея, так давайте сделаем еще больше пространств имен!

—Тим Питерс (Tim Peters)
Эта «поэма» создавалась в шутку, но в действительности содержит много истин относительно философии Python.
В течение долгого времени Pythoneer Тим Питерс переложил принципы BDFL-руководства в 20 кратких афоризмов, только 19 из которых были записаны.
http://www.python.org/dev/peps/pep-0020/

Вы можете сами решить для себя, кто вы: «Pythoneer» или «Pythonista». Эти слова имеют сопутствующие значения.

Когда в сомнении:
import this<br/>

Попробуйте это в интерактивном интерпретаторе Python:
>>> import this<br/>

Вот другое «пасхальное яйцо»:
>>> from __future__ import braces<br/>
  File "<stdin></stdin>", line 1<br/>
SyntaxErrornot a chance<br/>

Что за сборище комедиантов! :-)


Стиль кодинга: читаемость важна (Coding Style: Readability Counts)


Программы должны быть написаны для чтения людьми и только по случайности для исполнения машинами.
—Abelson & Sussman, Structure and Interpretation of Computer Programs («Структура и интерпретация компьютерных программ»)

Попробуйте создавать свои программы легкочитаемыми и очевидными.

PEP 8: Руководство по стилю Python-кода


Стоит почитать:
http://www.python.org/dev/peps/pep-0008/

PEP = Python Enhancement Proposal (Предложения по развитию Python)
PEP является документом, представляющим информацию Python-сообществу, описывающим новые фичи Python-а, его процессов или окружения.
Python-сообщество имеет собственные стандарты, описывающие, как должен выглядеть исходный код, изложенные в PEP 8. Эти стандарты отличаются от других, таких как C, C++, C#, Java, VisualBasic и др.
Поскольку отступы и пробелы исключительно важны в Python, Руководство по стилю для Python-кода использует отступы по стандарту. Это мудро, что руководство придерживается руководства!.. Большинство опенс-соурс проектов и (надо надеяться) домашних тоже, следуют руководству довольно строго.


Пробелы 1


  • 4 пробела на один уровень отступа.
  • Нет табуляциям.
  • Никогда не смешивайте табуляцию и пробелы.
    Это точно поддерживается в IDLE и Emacs Python mode. Другие редакторы тоже могут уметь это.
  • Одна пустая строка между функциями.
  • Две пустых строки между классами.


Пробелы 2


  • Добавьте пробел после "," в словарях, списках, кортежах, списках аргументов, и после ":" в словарях, но не перед.
  • Вставьте пробелы вокруг присваиваний и сравнений (кроме списков аргументов).
  • Никаких пробелов внутри круглых скобок или перед списком аргументов.
  • Никаких пробелов в начале и конце строк документации.

def make_squares(key, value=0‌):<br/>
    """Return a dictionary and a list..."""<br/>
    d = {key: value}<br/>
    l = [key, value]<br/>
    return d, l<br/>


Именование


  • слитно_строчными для функций, методов, атрибутов
  • joined_lower или ВСЕ_КАПСОМ для констант
  • StudlyCaps для классов
  • camelCase только чтобы соответствовать предопределенным соглашениям
  • Атрибуты: interface, _internal, __private

    Попробуйте избегать __private форму. Я никогда не использую это. Поверьте мне. Если вы это используете, вы пожалеете об этом позже.
    Объяснение:

    Люди, пришедшие после C++/Java изначально склонны к неправильному и чрезмерному использованию этой «фичи». __private имена работают не так, как в Java или C++. Это просто «запускает» механизм преобразования имени(name mangling), что позволяет предотвратить случайные коллизии пространств имен в подклассах: MyClass.__private становится MyClass._MyClass__private. (Заметьте, что это работает даже для подклассов с тем же самым именеем, что у суперкласса, например подкласс, определенный в другом модуле.) Таким образом, возможен доступ к __private именам снаружи класса, однако неудобно и хрупко (это добавляет зависимость от точного имени суперкласса).
    Проблема в том, что автор класса закономерно может думать: «Это имя атрибута/метода должно быть приватным, доступным только внутри этого определения класса» и использовать __private объявление. Но позже, пользователь этого класса может создать подкласс, в котором ему законно нужен доступ к этому имени. Для этого суперкласс может быть изменен (что может быть затруднительно или невозможно), или в коде подкласса применить преобразование имени (mangled names) (что безобразно и хрупко в лучшем случае).

    Это концепция Python-а: «Мы все тут взрослые».
    Если вы используете __private форму, от кого вы защищаете атрибут? Это ответственность подклассов — использовать атрибуты суперкласса правильно, и ответственность суперкласса — документировать свои атрибуты верно.
    Для этих целей лучше использовать начинающееся с одного подчеркивания объявление, _internal. Это не преобразует имена; просто говорит другим «быть осторожнее с этим, это реализация внутренних механизмов; не трогайте это, если не понимаете это полностью». Все же это только соглашение.
    Есть несколько хороших объяснений в ответах здесь:



Длинные строки кода (Lines) и их продолжения


Держите длину строк кода в пределах 80 символов.
Используйте неявные продолжения строк внутри скобок:
def __init__(self, first, second, third,<br/>
             fourth, fifth, sixth):<br/>
    output = (first + second + third<br/>
              + fourth + fifth + sixth)<br/>

Используйте бэкслеш:
VeryLong.left_hand_side \<br/>
    = even_longer.right_hand_side()<br/>

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

Длинные строки (Strings)


Cмежные литеральные строки (символы) конкатенируются парсером:
>>> print 'o' 'n' "e"<br/>
one<br/>

Пробелы между литерами не требуются, но помогают сделать код более читаемым. Может быть использован любой тип кавычек:
>>> print 't' r'\/\/' """o"""<br/>
t\/\/o<br/>

Строки, начинающиеся с «r» являются «сырыми» (raw). Бэкслеши не считаются эскейп-симовлами в сырых строках. Они используются для регулярных выражений и путей в файловых системах Windows.
Заметьте, что именованные строковые объекты не конкатенируются:
>>> a = 'three'<br/>
>>> b = 'four'<br/>
>>> a b<br/>
  File "<stdin>", line 1<br/>
    a b<br/>
      ^<br/>
SyntaxError: invalid syntax<br/>

Это потому что автоматическая конкатенация — фича парсера Python (синтаксического анализатора), а не интерпретатора. Вы должны использовать оператор "+" для объединения строк в рантайме.

text = ('Long strings can be made up '<br/>
        'of several shorter strings.')<br/>

Круглые скобки позволяют неявное объединение строк кода.
Для задания многострочных строковых значений используйте тройные кавычки:

"""Triple<br/>
double<br/>
quotes"""
<br/>

'''\<br/>
Triple<br/>
single<br/>
quotes\<br/>
'''
<br/>

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


Составные операторы



Хорошо:
if foo == 'blah':<br/>
    do_something()<br/>
do_one()<br/>
do_two()<br/>
do_three()<br/>

Плохо:
if foo == 'blah': do_something()<br/>
do_one(); do_two(); do_three()<br/>

Пробелы и отступы — полезные визуальные индикаторы программного потока. Отступ второй строки «Хорошего» кода выше показывает читателю выполнение чего-то по условию, в то время как отсутствие отступа в «Плохо» прячет «if» условие.
Множество операторов на одной строке кода — основной грех. В Python, важна читаемость.



Строки документации и комментарии



Строки документации = Как использовать код

Комментарии = Почему (разумное обоснование) и как код работает
Строки документации объясняют как использовать код, и для пользователей вашего кода. Использование строк документации:
  • Объясните цель функции, даже если это кажется вам очевидным, потому что это может оказаться неочевидным кому-нибудь позже.
  • Опишите ожидаемые параметры, возвращаемые значения, и любые вызываемые исключения.
  • Если метод плотно связан с единственным вызовом, создайте какую-нибудь связь с вызывающим оператором (хотя будьте осторожны, потому что вызывающий оператор может измениться впоследствии).

Комментарии объясняют почему и нужны для майнтайнеров вашего кода. Примеры включают заметки для себя, как:
# !!! BUG: ...<br/>
<br/>
# !!! FIX: This is a hack<br/>
<br/>
# ??? Why is this here?<br/>

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

Ложные комментарии и строки документации хуже, чем совсем ничего. Так сохраняйте их сразу! Когда вы делаете изменения, убедитесь, что комментарии и строки документации соответствуют коду и не противоречат ему.
В PEP есть целое соглашение о строках документации, PEP 257, «Docstring Conventions»:
http://www.python.org/dev/peps/pep-0257/



Практичность побеждает чистоту



Глупая согласованность — маленький монстр недалекого ума (A foolish consistency is the hobgoblin of little minds).
—Ralph Waldo Emerson

(hobgoblin: Что-то, вызывающее суеверный страх)
(примеч. перев.: Как я понял, смысл такой: «Научи дурака богу молиться — он себе лоб расшибет»)
Всегда есть исключения. Из PEP 8:
Очень важно, когда возникнет противоречие — бывает так, что следование руководству просто не приемлемо. Когда сомневаетесь, используйте решение, наилучшее на ваш взгляд. Посмотрите на другие примеры и решите, какая точка зрения лучше. И не стесняйтесь спрашивать!
Две хороших причины ломать принятые правила:
  1. При следовании правилам код становится менее удобочитаемым, даже для кого-нибудь, кто привык следовать правилам.
  2. Чтобы соответствовать окружающему коду, тоже можно нарушать (это может быть по историческим причинам) — хотя это может оказаться возможностью навести порядок в чьей-то путанице (в тру-ХР стиле (eXtreme Programming — примеч. перев.)).



… но практичность не должна нарушать чистоту постоянно!

Попурри из идиом


Выборка небольших, полезных идиом.
Теперь мы переходим к основной части туториала: множество идиом.
Мы начнем с тех, что полегче и постепенно поднимем уровень.



Обмен значений


В других языках:
temp = a<br/>
= b<br/>
= temp<br/>

В Python:
b, a = a, b<br/>

Возможно, вы видели это прежде. Но знаете ли вы, как это работает?
  • Запятая является синтаксисом конструктора кортежа.
  • Справа создается кортеж (упаковка кортежа).
  • Кортеж слева является целью присваивания (распаковка кортежа).


Правая сторона распакована по именам в кортеж с левой стороны.
Еще примеры распаковки:
>>> l =['David''Pythonista''+1-514-555-1234']<br/>
>>> name, title, phone = l<br/>
>>> name<br/>
'David'<br/>
>>> title<br/>
'Pythonista'<br/>
>>> phone<br/>
'+1-514-555-1234'<br/>

Полезно в циклах для обработки структурированных данных:

Выше мы создали список (David's info). people — список людей, содержащий два элемента, каждый из которых является списком из трех элементов.
>>> people = [l, ['Guido''BDFL''unlisted']]<br/>
>>> for (name, title, phone) in people:<br/>
...     print name, phone<br/>
...<br/>
David +1-514-555-1234<br/>
Guido unlisted<br/>

Каждый элемент people был распакован в кортеж вида (name, title, phone).
Только не забудьте соответствровать структуре слева и справа!
>>> david, (gname, gtitle, gphone) = people<br/>
>>> gname<br/>
'Guido'<br/>
>>> gtitle<br/>
'BDFL'<br/>
>>> gphone<br/>
'unlisted'<br/>
>>> david<br/>
['David''Pythonista''+1-514-555-1234']<br/>



Еще о кортежах


Мы видели, как запятая была конструктором кортежа, без круглых скобок. Пример:
>>> 1,<br/>
(1,)<br/>

Интерпретатор Python-а показывает скобки для ясности, и я рекомендую вам тоже их использовать:

>>> (1,)<br/>
(1,)<br/>

Не забывайте запятую!
>>> (1)<br/>
1<br/>

В кортеже из одного элемента требуется конечная запятая; в 2+-кортежах, конечная запятая опциональна. В 0-кортежах, или пустых кортежах, пара круглых скобок является укороченным синтаксисом:
>>> ()<br/>
()<br/>

>>> tuple()<br/>
()<br/>

Общепринятая опечатка — оставить запятую в коде, даже если вы не хотите создавать кортеж. Её легко можно пропустить в вашем коде:
>>> value = 1,<br/>
>>> value<br/>
(1,)<br/>

Таким образом, если вы видите кортеж, где не ждали, поищите запятую!


Интерактивное "_"



Это действительно полезная фича, удивительно, что немногие знают о ней.

В интерактивном режиме интерпретатора, всякий раз, когда вы пробуете выражение или вызов функции, результат сохраняется во временной переменной, _ (подчеркивание):

>>> 1 + 1<br/>
2<br/>
>>> _<br/>
2<br/>

_ хранит последнее напечатанное командой print выражение. Это удобно!
Но работает только в интерактивном режиме интерпретатора, не в модулях.

Особенно полезно, когда вы прорабатываете задачу в интерактивном режиме и хотите сохранить результат для следующего шага:

>>> import math<br/>
>>> math.pi / 3<br/>
1.0471975511965976<br/>
>>> angle = _<br/>
>>> math.cos(angle)<br/>
0.50000000000000011<br/>
>>> _<br/>
0.50000000000000011<br/>



Составление строк из подстрок


Начнем со списка из строк:
colors = ['red''blue''green''yellow']<br/>

Мы хотим соединить все строки вместе в одну большую строку. Особенно, когда подстрок много…

не делайте так:
result = ''<br/>
for s in colors:<br/>
    result += s<br/>

Это очень неэффективно.

Это ужасно съедает память и ухудшает производительность. «Суммирование» вычисляет, сохраняет и потом уничтожает объект на каждом промежуточном шаге.


Вместо этого, делайте так:
result = ''.join(colors)<br/>

Метод строк join() делает все копирования в один проход.
Когда вы имеете дело с парой дюжин или сотен строк, это не даст заметной разницы. Но привыкайте собирать строки эффективно, потому что это даст выигрыш при тысячах строк и при работе в циклах.



Составление строк, вариация 1


Вот некоторые способы использования метода join().

Если вы хотите расставить пробелы между вашими подстроками:
result = ' '.join(colors)<br/>

Или запятые и пробелы:
result = ', '.join(colors)<br/>

В общем случае:
colors = ['red''blue''green''yellow']<br/>
print 'Choose'', '.join(colors[:-1]), \<br/>
      'or', colors[-1]<br/>

Чтобы составить грамматически правильное предложение, мы хотим поставить запятую между всеми значениями, а перед последним слово «or». Тут помогает синтаксис срезов. «Срез до -1» ([:-1]) выдает индекс предпоследнего элемента который мы будем присоединять через запятую с пробелом.
Конечно, этот код не захочет работать в случаях, когда длина списка равна 0 или 1.

Вывод:
Choose red, blue, green or yellow<br/>


Составление строк, вариация 2


Если вам нужно применить функцию для генерации подстрок:
result = ''.join(fn(i) for i in items)<br/>

Здесь используется выражение-генератор, которое мы рассмотрим позже.

Если вам понадобилось вычислить подстроки пошагово, соберите их сначала в список:
items = []<br/>
...<br/>
items.append(item)  # many times<br/>
...<br/>
# items is now complete<br/>
result = ''.join(fn(i) for i in items)<br/>

Мы собрали части в список так, что мы можем применить теперь метод строк join
для большей эффективности.





Вторая часть перевода



Автор оригинала: David Goodger
kossmak @kossmak
карма
52,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (30)

  • +5
    если только вы не из Голландии (видимо имеется ввиду «травокур» — прим. перев.)

    Не травокур, а Гвидо ван Россум имелся в виду =) Из Голландии он.
    • 0
      Спасибо большое, а то я мозг сломал, пытаясь угадать тайный смысл)) Как считаете, в тексте в примечании стоит указать его?
      • +2
        Думаю, стоит, а то уличат в скрытой пропаганде лигалайза)
  • 0
    Хорошая подборка )
  • 0
    Психоделично…
    • 0
      Кстати, да, тоже показалось, не самый обычный и простой стиль изложения. Местами очень сложно решить, правильно ли понята мысль автора.
  • –1
    А почему нельзя табуляции, а надо 4 пробела?
    • 0
      Потому, что таб может быть длиной и 2, 4 и 8 символов — могут возникнуть проблемы при редактировании файла несколькими людьми в редакторах, который настроены по-разному. А 4 пробела — они всегда 4 пробела.
      • –3
        Таб также может быть просто табом… Согласен, могут быть неувязки, когда в одном редакторе таб 4 пробела, в другом он таб, но выглядит как четыре пробела…
        Но разве это удобно?
        • 0
          Проблемы будут, когда в пределах одного файла будут встречаться отступы сделанные и табами и пробелами.

          ЗЫ. Если вы один редактируете файл — все равно.
          • +1
            там же следом написано — не смешивайте табы и пробелы — в этом и есть зло. а табы они всегда табы, сколько бы места ни занимали.
        • 0
          Если использовать редактор, умеющий заменять табуляции на заданное (настраиваемое) число пробелов, то очень удобно.
          Жмешь ли Таб, отщелкиваешь ли пробелы, умный редактор рисует именно пробелы.
          В 21-м веке обещали в большинстве редакторов сделать автоотступ:
          — по предыдущей строке
          — даже по семантике, например, после условия if следующая строка, вложенный блок, будет отбиваться с необходимым сдвигом вправо.
          Рекомендую посмотреть на notepad++ и особенно понравился Pyscripter
          • 0
            Да про автоотступы я слышал ) Не видел, чтоб можно было настраивать, чтоб таб был определённым количеством пробелов… Pyscripter посмотрю, спасибо, у вас, кстати, на него ссылка поламалась, ну та ничё
            • +1
              Движок Хабра чудеса творит порой.
              Я два дня не мог опубликовать перевод из-за того, что скрипт проверки ссылки на оригинал статьи не пропускал URL, содержащий тильду "~".
              Чудом догадался подменить ее на шестнадцатеричный код "%7E". Саппорту про багу отписал.
  • +3
    PEP 8 — Style Guide for Python Code уже переведён, между прочим.
    Вот на goggle docs.
  • 0
    Спасибо за перевод, думаю, многим будет полезно

    Советую взять сторонний перевод дзена. Например, с Википедии

    Style Guide от Google
    • –1
      Спасибо, пожалуй, последую вашему совету, но чуть позже. Хочется посмотреть, как будет оценен сообществом именно мой труд.
      Вообще, в планах было предоставить русскоязычный перевод автору статьи. По адресу http://python.net/~goodger/projects/pycon/2007/idiomatic/ он уже расположил ссылку на французский вариант. Собственно, это меня и подтолкнуло меня приложить старание.
      Разумеется, автору будет выслан вариант, скорректированный с учетом замечаний читателей Хабра.
  • –1
    Уже ждем продолжение =)
  • +3
    > Пространства имен — грандиозная идея, позволяют делать еще больше из них же!

    Гугл-транслейт не вмешивался?
    Оригинальное «let's do more of those!» переводится как «так давайте же сделаем больше пространств имен!»
    • +2
      кстати, в «Code Like a Pythonista» Code — это однозначно глагол. «Пиши как настоящий питонщик», как-то так.

      С Pythonista тоже трудно — если переводить «питонист», но оттенок теряется, т.к. тут суффикс не наш обычный "-ист" (как «программист»), а испанский "-ista":

      suffix informal
      forming nouns denoting a person associated with a particular activity, often with a derogatory intent: fashionista.
      ORIGIN from the Spanish suffix -ista, as in Sandinista.
      • 0
        Я человек, измученный нарзаном немецким в школе. Знакомство с английским произошло через компьютеры, через них же и обучение. С произношением еще хуже, чем с грамматикой, определенно. Знал, что скорее всего неверно понял название, потому и оставил в заголовке оригинал. Все замечания учтем.
        Для себя решил, Pythonista — питонист, Pythoneer — питонер. Созвучно, и недалеко от смысла. «Питонщик» как-то коробит (мойщик, грузчик, гладильщик)
    • 0
      Нет, такое мог придумать только я) Вариант переводчиков мне понравился меньше. А вам спасибо, сейчас подправлю.
  • 0
    Однозначно ждем продолжения!
    В последнее время питон набирает популярность, с одной стороны это не может не радовать, появляется много интересных статей, а с другой стороны немного страшно за родной язык, как бы его не постигла участь PHP, когда из-за низкого порога входимости в язык, и большого кол-ва мануалов появляется огромное кол-во «программистов» мнящих себя гуру.
    • 0
      [irony]За родной язык и вправду страшно, и за порог входимости, и за культурный уровень его носителей, если вы про русский. [/irony]
      Тут скорее не про участь речь должна быть, а про сферу применения, целевую аудиторию, сообщество, развивающее язык. В случае с Python все это чуточку упорядоченней, более академично что ли.
      Не вижу связи между сложностью языка и качеством программистов. «Индусов», кодящих на C++ все хвалят? Мало удачных проектов на Delphi?
      Все зависит от конкретных людей.
      Python — боле-менее универсальный инструмент для решения различных задач, и в его философию заложено быть удобным к прочтению/пониманию. Не переживайте, язык не только перспективный, но и со светлым будущим.
  • 0
    Хорошая статья для новичков. Спасибо.
  • 0
    Есть вопрос: как думаете, с чем связана привычка не отбивать пробелами знак = при передаче именованных аргументов функции? насколько это строгое правило?
    Мне после php как-то непривычно)
    • 0
      Основной акцент всей статьи — удобочитаемость важнее всего. PEP-рулевые решили, что так красивее и практичнее.
      Отбивать пробелы между именем и значением аргумента или не отбивать — все-таки на вашей совести остается, интерпретатор проглотит. Но я в этом месте склоняюсь к рекомендации PEP.
      Python допускает указание аргументов функции в виде голых значений, но в строгом соответствии с их порядком в объявлении, для удобства после каждой запятой большинство кодеров отбивают пробел:

      a = my_func(1, 2, 'arg3')
      

      Но равновозможно и равноправильно допускается указать аргументы поименно. При этом, скорее всего, вы тоже отобьете пробелы после запятых. Визуально по количеству запятых-пробелов можно ухватить глазом, сколько аргументов передано в функцию.
      При этом, если отщелкать пробелами еще и "=", то такое быстрое хватание взглядом становится затруднительным, сравните два варианта кода (я нарочно прилепил еще if с несколькими условиями):

      def my_func(num, name, descr, age=20):
          ...
      
      # вариант 1
      if a = b and a >= 0:
          res = my_func(1, 'Joe', 'long_long_string', 10)      
      else:
          res = my_func(num=2, descr='another_string', name='Lissy', age=18)
      
      # вариант 2
      if a = b and a >= 0:
          res = my_func(descr = 'long_long_string2', num = 1, name = 'Bill')      
      

      Мне точно удобнее разобрать количество аргументов в первом варианте
      • 0
        Спасибо за ответ. Единственное, я немного подозреваю, что подсветка синтаксиса может ухудшить первый вариант и улучшить второй в плане читаемости (т.к. в первом варианте каждая из групп, например, со строками будет двухцветной, что раздробит её).
        • 0
          # вариант 1
          if a = b and a >= 0‌:
              res = my_func(1'Joe''long_long_string'10)      
          else:
              res = my_func(num=2, descr='another_string', name='Lissy', age=18)

          # вариант 2
          if a = b and a >= 0‌:
              res = my_func(descr = 'long_long_string2', num = 1, name = 'Bill')   
          • 0
            Вроде разница уменьшилась.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.