controlflow.md
1> **Источник:** https://python-all.ru/3.6/tutorial/controlflow.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 4. Дополнительные средства управления потоком89Помимо только что представленного оператора [`while`](https://python-all.ru/3.6/reference/compound_stmts.html#while), Python поддерживает обычные операторы управления потоком, знакомые по другим языкам, но с некоторыми отличиями.1011## 4.1. [`if`](https://python-all.ru/3.6/reference/compound_stmts.html#if)Инструкции1213Пожалуй, наиболее известным типом оператора является оператор [`if`](https://python-all.ru/3.6/reference/compound_stmts.html#if). Например:1415```python16>>> x = int(input("Please enter an integer: "))17Please enter an integer: 4218>>> if x < 0:19... x = 020... print('Negative changed to zero')21... elif x == 0:22... print('Zero')23... elif x == 1:24... print('Single')25... else:26... print('More')27...28More29```3031Может быть ноль или более частей [`elif`](https://python-all.ru/3.6/reference/compound_stmts.html#elif), а часть [`else`](https://python-all.ru/3.6/reference/compound_stmts.html#else) является необязательной. Ключевое слово ‘[`elif`](https://python-all.ru/3.6/reference/compound_stmts.html#elif)’ является сокращением от ‘else if’ и полезно для избежания чрезмерного отступа. Последовательность [`if`](https://python-all.ru/3.6/reference/compound_stmts.html#if) … [`elif`](https://python-all.ru/3.6/reference/compound_stmts.html#elif) … [`elif`](https://python-all.ru/3.6/reference/compound_stmts.html#elif) … является заменой операторов `switch` или `case`, встречающихся в других языках.3233## 4.2. [`for`](https://python-all.ru/3.6/reference/compound_stmts.html#for)Инструкции3435Оператор [`for`](https://python-all.ru/3.6/reference/compound_stmts.html#for) в Python немного отличается от того, к чему вы могли привыкнуть в C или Pascal. Вместо того чтобы всегда выполнять итерацию по арифметической прогрессии чисел (как в Pascal) или давать пользователю возможность задавать как шаг итерации, так и условие остановки (как в C), оператор [`for`](https://python-all.ru/3.6/reference/compound_stmts.html#for) в Python выполняет итерацию по элементам любой последовательности (списка или строки) в том порядке, в котором они встречаются в последовательности. Например (без каламбура):3637```python38>>> # Измеряем некоторые строки:39... words = ['cat', 'window', 'defenestrate']40>>> for w in words:41... print(w, len(w))42...43cat 344window 645defenestrate 1246```4748Если требуется изменить последовательность, по которой выполняется итерация, внутри цикла (например, для дублирования выбранных элементов), рекомендуется сначала создать копию. Итерация по последовательности не создаёт копию неявно. Синтаксис среза делает это особенно удобным:4950```python51>>> for w in words[:]: # Выполнить итерацию по копии среза всего списка.52... if len(w) > 6:53... words.insert(0, w)54...55>>> words56['defenestrate', 'cat', 'window', 'defenestrate']57```5859С `for w in words:` пример попытался бы создать бесконечный список, вставляя `defenestrate` снова и снова.6061## 4.3. Функция [`range()`](https://python-all.ru/3.6/library/stdtypes.html#range)6263Если вам действительно нужно выполнить итерацию по последовательности чисел, встроенная функция [`range()`](https://python-all.ru/3.6/library/stdtypes.html#range) оказывается полезной. Она генерирует арифметические прогрессии:6465```python66>>> for i in range(5):67... print(i)68...69070171272373474```7576Указанная конечная точка никогда не входит в сгенерированную последовательность; `range(10)` генерирует 10 значений – допустимые индексы для элементов последовательности длины 10. Можно заставить диапазон начинаться с другого числа или указать другой шаг (даже отрицательный; иногда это называется «шаг»):7778```python79range(5, 10)80 5, 6, 7, 8, 98182range(0, 10, 3)83 0, 3, 6, 98485range(-10, -100, -30)86 -10, -40, -7087```8889Для итерации по индексам последовательности можно комбинировать [`range()`](https://python-all.ru/3.6/library/stdtypes.html#range) и [`len()`](https://python-all.ru/3.6/library/functions.html#len) следующим образом:9091```python92>>> a = ['Mary', 'had', 'a', 'little', 'lamb']93>>> for i in range(len(a)):94... print(i, a[i])95...960 Mary971 had982 a993 little1004 lamb101```102103Однако в большинстве таких случаев удобно использовать функцию [`enumerate()`](https://python-all.ru/3.6/library/functions.html#enumerate), см. [Техники циклической обработки](https://python-all.ru/3.6/tutorial/datastructures.html#tut-loopidioms).104105Странная вещь происходит, если просто вывести range:106107```python108>>> print(range(10))109range(0, 10)110```111112Во многих отношениях объект, возвращаемый [`range()`](https://python-all.ru/3.6/library/stdtypes.html#range), ведёт себя как список, но на самом деле это не так. Это объект, который при итерации возвращает последовательные элементы нужной последовательности, но на самом деле не создаёт список, экономя тем самым память.113114Говорят, что такой объект является *итерируемым*, то есть пригодным в качестве цели для функций и конструкций, которые ожидают нечто, из чего можно последовательно получать элементы, пока запас не иссякнет. Мы видели, что оператор [`for`](https://python-all.ru/3.6/reference/compound_stmts.html#for) является таким *итератором*. Функция [`list()`](https://python-all.ru/3.6/library/stdtypes.html#list) – ещё один пример; она создаёт списки из итерируемых объектов:115116```python117>>> list(range(5))118[0, 1, 2, 3, 4]119```120121Позже мы увидим больше функций, которые возвращают итерируемые объекты и принимают их в качестве аргумента.122123## 4.4. [`break`](https://python-all.ru/3.6/reference/simple_stmts.html#break) и [`continue`](https://python-all.ru/3.6/reference/simple_stmts.html#continue) операторы, и [`else`](https://python-all.ru/3.6/reference/compound_stmts.html#else) предложения в циклах124125Оператор [`break`](https://python-all.ru/3.6/reference/simple_stmts.html#break), как и в C, прерывает выполнение самого внутреннего цикла [`for`](https://python-all.ru/3.6/reference/compound_stmts.html#for) или [`while`](https://python-all.ru/3.6/reference/compound_stmts.html#while).126127Операторы цикла могут иметь предложение `else`; оно выполняется, когда цикл завершается исчерпанием списка (с [`for`](https://python-all.ru/3.6/reference/compound_stmts.html#for)) или когда условие становится ложным (с [`while`](https://python-all.ru/3.6/reference/compound_stmts.html#while)), но не когда цикл прерван оператором [`break`](https://python-all.ru/3.6/reference/simple_stmts.html#break). Это демонстрируется следующим циклом, который ищет простые числа:128129```python130>>> for n in range(2, 10):131... for x in range(2, n):132... if n % x == 0:133... print(n, 'equals', x, '*', n//x)134... break135... else:136... # цикл завершился без нахождения множителя137... print(n, 'is a prime number')138...1392 is a prime number1403 is a prime number1414 equals 2 * 21425 is a prime number1436 equals 2 * 31447 is a prime number1458 equals 2 * 41469 equals 3 * 3147```148149(Да, это правильный код. Присмотритесь: предложение `else` относится к циклу [`for`](https://python-all.ru/3.6/reference/compound_stmts.html#for), **а не** к инструкции [`if`](https://python-all.ru/3.6/reference/compound_stmts.html#if).)150151При использовании с циклом предложение `else` имеет больше общего с `else` предложением оператора [`try`](https://python-all.ru/3.6/reference/compound_stmts.html#try), чем с предложением операторов [`if`](https://python-all.ru/3.6/reference/compound_stmts.html#if): предложение `else` оператора [`try`](https://python-all.ru/3.6/reference/compound_stmts.html#try) выполняется, когда не возникает исключения, а предложение `else` цикла выполняется, когда не происходит `break`. Подробнее об операторе [`try`](https://python-all.ru/3.6/reference/compound_stmts.html#try) и исключениях см. [Обработка исключений](https://python-all.ru/3.6/tutorial/errors.html#tut-handling).152153Оператор [`continue`](https://python-all.ru/3.6/reference/simple_stmts.html#continue), также заимствованный из C, переходит к следующей итерации цикла:154155```python156>>> for num in range(2, 10):157... if num % 2 == 0:158... print("Found an even number", num)159... continue160... print("Found a number", num)161Found an even number 2162Found a number 3163Found an even number 4164Found a number 5165Found an even number 6166Found a number 7167Found an even number 8168Found a number 9169```170171## 4.5. [`pass`](https://python-all.ru/3.6/reference/simple_stmts.html#pass)Инструкции172173Инструкция [`pass`](https://python-all.ru/3.6/reference/simple_stmts.html#pass) ничего не делает. Она может использоваться, когда синтаксически требуется инструкция, но программа не должна выполнять никаких действий. Например:174175```python176>>> while True:177... pass # Активное ожидание прерывания с клавиатуры (Ctrl+C)178...179```180181Это часто используется для создания минимальных классов:182183```python184>>> class MyEmptyClass:185... pass186...187```188189Ещё одно место, где можно использовать [`pass`](https://python-all.ru/3.6/reference/simple_stmts.html#pass) – в качестве заполнителя для тела функции или условного оператора при работе над новым кодом, позволяя сохранять более абстрактный уровень мышления. [`pass`](https://python-all.ru/3.6/reference/simple_stmts.html#pass) молча игнорируется:190191```python192>>> def initlog(*args):193... pass # Не забудьте реализовать это!194...195```196197## 4.6. Определение функций198199Можно создать функцию, которая выводит ряд Фибоначчи до произвольной границы:200201```python202>>> def fib(n): # вывести ряд Фибоначчи до n203... """Вывести ряд Фибоначчи до n."""204... a, b = 0, 1205... while a < n:206... print(a, end=' ')207... a, b = b, a+b208... print()209...210>>> # Теперь вызовите только что определённую функцию:211... fib(2000)2120 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597213```214215Ключевое слово [`def`](https://python-all.ru/3.6/reference/compound_stmts.html#def) вводит *определение* функции. За ним должны следовать имя функции и список формальных параметров в скобках. Инструкции, составляющие тело функции, начинаются со следующей строки и должны иметь отступ.216217Первый оператор тела функции может быть строковым литералом; этот строковый литерал является строкой документации функции, или *docstring*. (Подробнее о docstring можно найти в разделе [Строки документации](https://python-all.ru/3.6/tutorial/controlflow.html#tut-docstrings).) Существуют инструменты, которые используют docstring для автоматического создания онлайн- или печатной документации, или чтобы позволить пользователю интерактивно просматривать код; рекомендуется включать docstring в код, который вы пишете, так что сделайте это привычкой.218219При *выполнении* функции создаётся новая таблица символов, используемая для локальных переменных функции. Точнее, все присваивания переменных в функции сохраняют значение в локальной таблице символов; тогда как ссылки на переменные сначала ищут в локальной таблице символов, затем в локальных таблицах символов окружающих функций, затем в глобальной таблице символов и, наконец, в таблице встроенных имён. Таким образом, глобальным переменным нельзя напрямую присвоить значение внутри функции (если только они не указаны в операторе [`global`](https://python-all.ru/3.6/reference/simple_stmts.html#global)), хотя на них можно ссылаться.220221Фактические параметры (аргументы) вызова функции вносятся в локальную таблицу символов вызываемой функции при её вызове; таким образом, аргументы передаются с использованием *передачи по значению* (где *значение* всегда является ссылкой *на объект*, а не значением объекта). [1](https://python-all.ru/3.6/tutorial/controlflow.html#id2) Когда функция вызывает другую функцию, для этого вызова создаётся новая локальная таблица символов.222223Определение функции вводит имя функции в текущую таблицу символов. Значение имени функции имеет тип, который распознаётся интерпретатором как определяемая пользователем функция. Это значение может быть присвоено другому имени, которое затем также можно использовать как функцию. Это служит общим механизмом переименования:224225```python226>>> fib227<function fib at 10042ed0>228>>> f = fib229>>> f(100)2300 1 1 2 3 5 8 13 21 34 55 89231```232233Приходя из других языков, вы можете возразить, что `fib` – это не функция, а процедура, поскольку она не возвращает значение. На самом деле даже функции без оператора [`return`](https://python-all.ru/3.6/reference/simple_stmts.html#return) возвращают значение, хотя и довольно скучное. Это значение называется `None` (это встроенное имя). Запись значения `None` обычно подавляется интерпретатором, если оно было бы единственным записанным значением. Вы можете увидеть его, если действительно захотите, с помощью [`print()`](https://python-all.ru/3.6/library/functions.html#print):234235```python236>>> fib(0)237>>> print(fib(0))238None239```240241Просто написать функцию, которая возвращает список чисел ряда Фибоначчи, вместо того чтобы выводить его:242243```python244>>> def fib2(n): # возвращает ряд Фибоначчи до n245... """Возвращает список, содержащий ряд Фибоначчи до n."""246... result = []247... a, b = 0, 1248... while a < n:249... result.append(a) # см. ниже250... a, b = b, a+b251... return result252...253>>> f100 = fib2(100) # вызов254>>> f100 # вывод результата255[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]256```257258Этот пример, как обычно, демонстрирует некоторые новые возможности Python:259260- Оператор [`return`](https://python-all.ru/3.6/reference/simple_stmts.html#return) возвращает значение из функции. [`return`](https://python-all.ru/3.6/reference/simple_stmts.html#return) без выражения-аргумента возвращает `None`. Завершение функции без явного возврата также возвращает `None`.261- Оператор `result.append(a)` вызывает *метод* объекта списка `result`. Метод – это функция, которая «принадлежит» объекту и имеет имя `obj.methodname`, где `obj` – некоторый объект (это может быть выражение), а `methodname` – имя метода, определённого типом объекта. Разные типы определяют разные методы. Методы разных типов могут иметь одинаковые имена без неоднозначности. (Можно определять собственные типы объектов и методы, используя *классы*; см. [Классы](https://python-all.ru/3.6/tutorial/classes.html#tut-classes)). Метод `append()`, показанный в примере, определён для объектов списка; он добавляет новый элемент в конец списка. В этом примере он эквивалентен `result = result + [a]`, но более эффективен.262263## 4.7. Подробнее об определении функций264265Также можно определять функции с переменным числом аргументов. Существует три формы, которые можно комбинировать.266267### 4.7.1. Значения аргументов по умолчанию268269Наиболее полезная форма – указать значение по умолчанию для одного или нескольких аргументов. Это создаёт функцию, которую можно вызывать с меньшим количеством аргументов, чем она определена допускать. Например:270271```python272def ask_ok(prompt, retries=4, reminder='Please try again!'):273 while True:274 ok = input(prompt)275 if ok in ('y', 'ye', 'yes'):276 return True277 if ok in ('n', 'no', 'nop', 'nope'):278 return False279 retries = retries - 1280 if retries < 0:281 raise ValueError('invalid user response')282 print(reminder)283```284285Эту функцию можно вызывать несколькими способами:286287- передавая только обязательный аргумент: `ask_ok('Do you really want to quit?')`288- передавая один из необязательных аргументов: `ask_ok('OK to overwrite the file?', 2)`289- или даже передавая все аргументы: `ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')`290291Этот пример также вводит ключевое слово [`in`](https://python-all.ru/3.6/reference/expressions.html#in). Оно проверяет, содержит ли последовательность определённое значение.292293Значения по умолчанию вычисляются в точке определения функции в *определяющей* области видимости, так что294295```python296i = 5297298def f(arg=i):299 print(arg)300301i = 6302f()303```304305выведет `5`.306307**Важное предупреждение:** Значение по умолчанию вычисляется только один раз. Это имеет значение, когда значение по умолчанию является изменяемым объектом, таким как список, словарь или экземпляры большинства классов. Например, следующая функция накапливает аргументы, переданные ей при последующих вызовах:308309```python310def f(a, L=[]):311 L.append(a)312 return L313314print(f(1))315print(f(2))316print(f(3))317```318319Это выведет320321```python322[1]323[1, 2]324[1, 2, 3]325```326327Если вы не хотите, чтобы значение по умолчанию разделялось между последующими вызовами, вы можете написать функцию так:328329```python330def f(a, L=None):331 if L is None:332 L = []333 L.append(a)334 return L335```336337### 4.7.2. Именованные аргументы338339Функции также можно вызывать с помощью [именованных аргументов](https://python-all.ru/3.6/glossary.html#term-keyword-argument) вида `kwarg=value`. Например, следующая функция:340341```python342def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):343 print("-- This parrot wouldn't", action, end=' ')344 print("if you put", voltage, "volts through it.")345 print("-- Lovely plumage, the", type)346 print("-- It's", state, "!")347```348349принимает один обязательный аргумент (`voltage`) и три необязательных аргумента (`state`, `action` и `type`). Эту функцию можно вызывать любым из следующих способов:350351```python352parrot(1000) # 1 позиционный аргумент353parrot(voltage=1000) # 1 именованный аргумент354parrot(voltage=1000000, action='VOOOOOM') # 2 именованных аргумента355parrot(action='VOOOOOM', voltage=1000000) # 2 именованных аргумента356parrot('a million', 'bereft of life', 'jump') # 3 позиционных аргумента357parrot('a thousand', state='pushing up the daisies') # 1 позиционный, 1 именованный358```359360но все следующие вызовы будут недопустимы:361362```python363parrot() # отсутствует обязательный аргумент364parrot(voltage=5.0, 'dead') # неименованный аргумент после именованного365parrot(110, voltage=220) # дублирование значения для одного и того же аргумента366parrot(actor='John Cleese') # неизвестный именованный аргумент367```368369В вызове функции именованные аргументы должны следовать за позиционными. Все переданные именованные аргументы должны соответствовать одному из аргументов, принимаемых функцией (например, `actor` не является допустимым аргументом для функции `parrot`), и их порядок не важен. Это также включает необязательные аргументы (например, `parrot(voltage=1000)` тоже допустим). Ни один аргумент не может получать значение более одного раза. Вот пример, который завершается ошибкой из-за этого ограничения:370371```python372>>> def function(a):373... pass374...375>>> function(0, a=0)376Traceback (most recent call last):377 File "<stdin>", line 1, in <module>378TypeError: function() got multiple values for keyword argument 'a'379```380381Когда присутствует последний формальный параметр вида `**name`, он получает словарь (см. [Типы отображений – dict](https://python-all.ru/3.6/library/stdtypes.html#typesmapping)), содержащий все именованные аргументы, кроме тех, которые соответствуют формальному параметру. Это может быть объединено с формальным параметром вида `*name` (описанным в следующем подразделе), который получает кортеж, содержащий позиционные аргументы, выходящие за пределы формальных параметров списка. (`*name` должен идти до `**name`.) Например, если определить функцию следующим образом:382383```python384def cheeseshop(kind, *arguments, **keywords):385 print("-- Do you have any", kind, "?")386 print("-- I'm sorry, we're all out of", kind)387 for arg in arguments:388 print(arg)389 print("-" * 40)390 for kw in keywords:391 print(kw, ":", keywords[kw])392```393394Её можно было бы вызвать так:395396```python397cheeseshop("Limburger", "It's very runny, sir.",398 "It's really very, VERY runny, sir.",399 shopkeeper="Michael Palin",400 client="John Cleese",401 sketch="Cheese Shop Sketch")402```403404и, конечно, она выведет:405406```text407-- Do you have any Limburger ?408-- I'm sorry, we're all out of Limburger409It's very runny, sir.410It's really very, VERY runny, sir.411----------------------------------------412shopkeeper : Michael Palin413client : John Cleese414sketch : Cheese Shop Sketch415```416417Обратите внимание, что порядок, в котором выводятся именованные аргументы, гарантированно соответствует порядку, в котором они были указаны в вызове функции.418419### 4.7.3. Произвольные списки аргументов420421Наконец, наименее часто используемая возможность – указать, что функцию можно вызывать с произвольным количеством аргументов. Эти аргументы будут упакованы в кортеж (см. [Кортежи и последовательности](https://python-all.ru/3.6/tutorial/datastructures.html#tut-tuples)). Перед переменным числом аргументов может быть ноль или более обычных аргументов.422423```python424def write_multiple_items(file, separator, *args):425 file.write(separator.join(args))426```427428Обычно эти аргументы `variadic` находятся последними в списке формальных параметров, потому что они собирают все остальные входные аргументы, переданные функции. Любые формальные параметры, которые следуют после `*args` параметра, являются аргументами, передаваемыми только по ключевому слову, то есть они могут использоваться только как ключевые, а не позиционные аргументы.429430```python431>>> def concat(*args, sep="/"):432... return sep.join(args)433...434>>> concat("earth", "mars", "venus")435'earth/mars/venus'436>>> concat("earth", "mars", "venus", sep=".")437'earth.mars.venus'438```439440### 4.7.4. Распаковка списков аргументов441442Обратная ситуация возникает, когда аргументы уже находятся в списке или кортеже, но их нужно распаковать для вызова функции, требующей отдельных позиционных аргументов. Например, встроенная функция [`range()`](https://python-all.ru/3.6/library/stdtypes.html#range) ожидает отдельные аргументы *start* и *stop*. Если они недоступны по отдельности, запишите вызов функции с оператором `*`, чтобы распаковать аргументы из списка или кортежа:443444```python445>>> list(range(3, 6)) # обычный вызов с отдельными аргументами446[3, 4, 5]447>>> args = [3, 6]448>>> list(range(*args)) # вызов с аргументами, распакованными из списка449[3, 4, 5]450```451452Аналогично, словари могут передавать именованные аргументы с помощью оператора `**`:453454```python455>>> def parrot(voltage, state='a stiff', action='voom'):456... print("-- This parrot wouldn't", action, end=' ')457... print("if you put", voltage, "volts through it.", end=' ')458... print("E's", state, "!")459...460>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}461>>> parrot(**d)462-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !463```464465### 4.7.5. Лямбда-выражения466467Небольшие анонимные функции можно создать с помощью ключевого слова [`lambda`](https://python-all.ru/3.6/reference/expressions.html#lambda). Эта функция возвращает сумму двух своих аргументов: `lambda a, b: a+b`. Лямбда-функции можно использовать везде, где требуются объекты функций. Синтаксически они ограничены одним выражением. Семантически это просто синтаксический сахар для обычного определения функции. Как и вложенные определения функций, лямбда-функции могут ссылаться на переменные из содержащей области видимости:468469```python470>>> def make_incrementor(n):471... return lambda x: x + n472...473>>> f = make_incrementor(42)474>>> f(0)47542476>>> f(1)47743478```479480В приведённом выше примере лямбда-выражение используется для возврата функции. Другое применение – передача небольшой функции в качестве аргумента:481482```python483>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]484>>> pairs.sort(key=lambda pair: pair[1])485>>> pairs486[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]487```488489### 4.7.6. Строки документации490491Вот некоторые соглашения о содержании и форматировании строк документации.492493Первая строка всегда должна быть кратким и сжатым описанием назначения объекта. Для краткости в ней не следует явно указывать имя или тип объекта, так как они доступны другими способами (кроме случая, когда имя оказывается глаголом, описывающим действие функции). Эта строка должна начинаться с заглавной буквы и заканчиваться точкой.494495Если в строке документации есть несколько строк, вторая строка должна быть пустой, чтобы визуально отделить краткое описание от остальной части. Последующие строки должны быть одним или несколькими абзацами, описывающими соглашения о вызове объекта, его побочные эффекты и т.д.496497Парсер Python не удаляет отступы из многострочных строковых литералов в Python, поэтому инструменты, обрабатывающие документацию, должны при необходимости удалять отступы. Это делается по следующему соглашению. Первая непустая строка *после* первой строки строки определяет величину отступа для всей строки документации. (Первую строку мы не можем использовать, так как она обычно примыкает к открывающим кавычкам строки, и её отступ не очевиден в строковом литерале.) Затем пробельные символы, «эквивалентные» этому отступу, удаляются из начала всех строк строки. Строки с меньшим отступом встречаться не должны, но если они встречаются, все их начальные пробелы должны быть удалены. Эквивалентность пробелов следует проверять после замены табуляции (обычно на 8 пробелов).498499Вот пример многострочной строки документации:500501```python502>>> def my_function():503... """Ничего не делает, но документирует.504...505... Нет, правда, он ничего не делает.506... """507... pass508...509>>> print(my_function.__doc__)510Do nothing, but document it.511512 No, really, it doesn't do anything.513```514515### 4.7.7. Аннотации функций516517[Аннотации функций](https://python-all.ru/3.6/reference/compound_stmts.html#function) – это полностью необязательная метаинформация о типах, используемых пользовательскими функциями (см. [**PEP 3107**](https://python-all.ru/3.6/tutorial/controlflow.html) и [**PEP 484**](https://python-all.ru/3.6/tutorial/controlflow.html) для получения дополнительной информации).518519Аннотации хранятся в атрибуте `__annotations__` функции в виде словаря и не влияют на любую другую часть функции. Аннотации параметров определяются двоеточием после имени параметра, за которым следует выражение, вычисляющее значение аннотации. Аннотации возвращаемого значения определяются литералом `->`, за которым следует выражение, между списком параметров и двоеточием, обозначающим конец оператора [`def`](https://python-all.ru/3.6/reference/compound_stmts.html#def). В следующем примере показаны позиционный аргумент, именованный аргумент и аннотированное возвращаемое значение:520521```python522>>> def f(ham: str, eggs: str = 'eggs') -> str:523... print("Annotations:", f.__annotations__)524... print("Arguments:", ham, eggs)525... return ham + ' and ' + eggs526...527>>> f('spam')528Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}529Arguments: spam eggs530'spam and eggs'531```532533## 4.8. Интермеццо: Стиль кодирования534535Теперь, когда вы собираетесь писать более длинные и сложные программы на Python, самое время поговорить о *стиле кодирования*. Большинство языков можно писать (или, точнее, *форматировать*) в разных стилях; одни стили более читаемы, чем другие. Облегчить чтение вашего кода другим – всегда хорошая идея, и принятие хорошего стиля кодирования в этом очень помогает.536537Для Python [**PEP 8**](https://python-all.ru/3.6/tutorial/controlflow.html) стал руководством по стилю, которому следуют большинство проектов; он продвигает очень читаемый и приятный глазу стиль кодирования. Каждый разработчик Python должен прочитать его в какой-то момент; вот наиболее важные моменты, извлечённые для вас:538539- Используйте отступы в 4 пробела и никаких табуляций.540541 4 пробела – хороший компромисс между маленьким отступом (позволяет большую глубину вложенности) и большим отступом (легче читать). Табуляция вносит путаницу, и её лучше избегать.542- Переносите строки так, чтобы они не превышали 79 символов.543544 Это помогает пользователям с маленькими экранами и позволяет размещать несколько файлов с кодом рядом на больших экранах.545- Используйте пустые строки для разделения функций и классов, а также крупных блоков кода внутри функций.546- По возможности размещайте комментарии на отдельных строках.547- Используйте строки документации.548- Используйте пробелы вокруг операторов и после запятых, но не непосредственно внутри скобочных конструкций: `a = f(1, 2) + g(3, 4)`.549- Давайте классам и функциям согласованные имена; принято использовать `CamelCase` для классов и `lower_case_with_underscores` для функций и методов. Всегда используйте `self` в качестве имени первого аргумента метода (см. [Первый взгляд на классы](https://python-all.ru/3.6/tutorial/classes.html#tut-firstclasses) для получения дополнительной информации о классах и методах).550- Не используйте экзотические кодировки, если ваш код предназначен для использования в международной среде. Стандартная кодировка Python, UTF-8 или даже обычный ASCII в любом случае подходят лучше всего.551- Аналогично, не используйте символы, не входящие в ASCII, в идентификаторах, если есть хоть малейшая вероятность, что код будут читать или сопровождать люди, говорящие на другом языке.552553Сноски554555**[1](https://python-all.ru/3.6/tutorial/controlflow.html#id1)**556557На самом деле, *вызов по ссылке на объект* было бы лучшим описанием, поскольку если передаётся изменяемый объект, вызывающий увидит любые изменения, вносимые вызываемым (например, элементы, добавленные в список).558