Главная / Курсы / Python / Синтаксические правила
# Глава 2. Синтаксические правила > Код, который так же понятен, как обычный английский. Одна из целей создания питона, озвученная автором языка Гвидо ван Россумом Рассмотрим структуру программы и основные синтаксические правила. Также вы узнаете, для чего нужны и чем различаются оператор `pass` и объект-синглтон «многоточие». ## Структура программы В Java, go, C++ и многих других языках точкой входа в приложение является метод `main()`. Такие языки объединяет нерушимое правило: нельзя просто написать код на уровне файла и запустить его. Питон — представитель скриптовых языков, и на него это правило не распространяется: с первой же строчки скрипта может начинаться бизнес-логика, не обернутая ни в какую функцию. Исходный код программы на питоне принято сохранять в файлах с расширением `.py`. Для запуска из консоли необходимо вызвать интерпретатор питона и первым аргументом указать имя файла. Допустим, исходный код в `example.py` состоит из одной строчки: ```python print("Dummy script, does nothing") ``` Тогда после запуска скрипта мы увидим в консоли ожидаемый вывод: ```shell $ python example.py Dummy script, does nothing ``` В этом коротком примере вся программа сводится к вызову встроенной функции `print()` для вывода текста. В ней нет подключения модулей, объявления переменных, классов. Что ж, усложним код. Пусть в консоль печатается текущее время: ```python {.example_for_playground} from datetime import datetime def print_time(): now = datetime.now() current_time = now.strftime("%H:%M:%S") print("Current Time:", current_time) print_time() ``` ``` Current Time: 13:19:20 ``` На первой строке из модуля `datetime` импортируется одноименный объект в глобальное пространство имен программы. Затем объявляется функция `print_time()`. Внутри нее у объекта `datetime` вызывается метод `now()` для получения текущего времени; оно преобразовывается в удобный формат и печатается в консоль. На последней строке объявленная функция `print_time()` вызывается. Пример демонстрирует общепринятую практику по **структурированию кода:** в начале файла импортируются нужные модули, затем объявляются какие-то глобальные переменные, функции и другие полезности, а в самом конце все это используется. ## Синтаксические правила С этих правил начинают свой путь все питонисты. **Вложенные блоки кода** отделяются отступами, а не фигурными скобками. Мы будем придерживаться [рекомендации из PEP8:](https://peps.python.org/pep-0008/#indentation) 1 отступ = 4 пробела. Вложенному блоку предшествует инструкция, заканчивающаяся двоеточием. Перед телом цикла — это условие цикла. Перед телом `if` — условие `if`. И так далее. Пример условия: ```python if user_is_active: get_next_command() else: close_session() ``` Пример цикла: ```python for item in items: process(item) ``` Пример функции: ```python def is_long(s): if len(s) > 79: return "string is too long" return "string has normal length" ``` Конец строки — это конец инструкции. Точка с запятой в конце не ставится. Пример с последовательным вызовом двух пользовательских функций. Никаких точек с запятой: ```python check_db_is_online() start_transaction() ``` Инициализируйте две переменные:{.task_text} - `a`, равную 8, на одной строке. - `b`, равную 10, на другой. ```python {.task_source #python_chapter_0020_task_0010} ``` Синтаксис: переменная = значение {.task_hint} ```python {.task_answer} a = 8 b = 10 ``` Исправьте синтаксические ошибки в коде. {.task_text} В данном коде используется функция `range(a, b)`, позволяющая получить последовательность от целого числа `a` до целого числа `b` не включительно. {.task_text} ```python {.task_source #python_chapter_0020_task_0020} for i in range(1, 10); print(i); ``` Нужно заменить точку с запятой в конце цикла на двоеточие. Удалить точку с запятой после `print()` и перенести вызов `print()` на новую строку с отступом. {.task_hint} ```python {.task_answer} for i in range(1, 10): print(i) ``` Если инструкция не влезает в строку (например, становится длиннее рекомендованных PEP8 79 символов), ее можно разбить на несколько строк с использованием круглых скобок. Первая строка в этом примере занимает 92 символа: ```python while retries_count < max_retries and service_is_up and not cancelled and request_is_ready: send_request() ``` Приведем ее в соответствие с PEP8: ```python while ( retries_count < max_retries and service_is_up and not cancelled and request_is_ready ): send_request() ``` Разбейте условие `if` на две строки или более. {.task_text} ```python {.task_source #python_chapter_0020_task_0030} MAX_SESSIONS = 5 MAX_QUEUE_LEN = 100 sessions_count = 9 queue_tasks = ["task1", "task2"] # Here we create list of strings error_in_request = True if sessions_count > MAX_SESSIONS or len(queue_tasks) > MAX_QUEUE_LEN or error_in_request: print("Error handling request") ``` Для разбиения условия на несколько строк возьмите его в круглые скобки. {.task_hint} ```python {.task_answer} MAX_SESSIONS = 5 MAX_QUEUE_LEN = 100 sessions_count = 9 queue_tasks = ["task1", "task2"] # Here we create list of strings error_in_request = True if ( sessions_count > MAX_SESSIONS or len(queue_tasks) > MAX_QUEUE_LEN or error_in_request ): print("Error handling request") ``` ## Исключения из правил Из этих несложных правил есть и исключения. Но их лучше избегать, чтобы не снижать читаемость кода. Тем не менее вы можете натолкнуться на злоупотребление ими в чужом коде. Например, несколько простых инструкций в одной строке не являются ошибкой. Друг от друга они отделяются точкой с запятой. В этом примере переменным `x` и `y` присваиваются результаты пользовательских функций: ```python x = x_offset(); y = y_offset(); print(x, y) ``` Сделайте этот код более читабельным. Одна строка — одна инструкция. {.task_text} ```python {.task_source #python_chapter_0020_task_0040} x = 5; y = 8; print(x, y) ``` Должно получиться 3 строки: 2 для инициализации переменных и 1 на вызов функции. {.task_hint} ```python {.task_answer} x = 5 y = 8 print(x, y) ``` Также допустимо размещать инструкцию и ее вложенный блок на одной строке. Это сработает, если сам вложенный блок не содержит каких-то своих вложенных инструкций: ```python while is_active: send_request() ``` Перепишите этот код, чтобы вложенный блок `while` шел на отдельной строке. {.task_text} В коде заводится функция `send_request()`, которая затем вызывается в цикле `while`. {.task_text} ```python {.task_source #python_chapter_0020_task_0050} def send_request(): # some business logic return False is_active = True while is_active: is_active = send_request() ``` Тело цикла должно идти на отдельной строке с отступом. {.task_hint} ```python {.task_answer} def send_request(): # some business logic return False is_active = True while is_active: is_active = send_request() ``` ## Оператор pass Бывают случаи, когда вложенный блок требуется оставить пустым. Например, ловить исключение, но не совершать дополнительных действий для его обработки: ```python try: send_request(data) except Exception: # Do nothing ``` Но пустой вложенный блок — это синтаксическая ошибка: ``` SyntaxError: unexpected EOF while parsing ``` Чтобы ее избежать, был придуман оператор `pass`. Это [ассемблеровский NOP](https://en.wikipedia.org/wiki/NOP_(code)) в мире питона. Так сказать оператор «отсутствие оператора». Теперь синтаксической ошибки не будет: ```python try: send_request(data) except Exception: pass ``` Добавьте `pass` в цикл, чтобы устранить ошибку интерпретатора. {.task_text} ```python {.task_source #python_chapter_0020_task_0060} n = 101 while n < 100: ``` Перед оператором `pass` не забудьте сделать отступ. {.task_hint} ```python {.task_answer} n = 101 while n < 100: pass ``` ## Многоточие В питоне существует объект-синглтон «многоточие», привязанный к константе с именем `Ellipsis` и литералу `...`: ```python {.example_for_playground} print(Ellipsis) print(...) ``` ``` Ellipsis Ellipsis ``` У многоточия несколько вариантов использования, и наиболее распространенный — это проставление вместо ключевого слова `pass`. Об остальных применениях (расширенный синтаксис срезов, аннотации типов и т.д.) мы поговорим в следующих главах. ```python def handle_request(req): ... ``` При этом многоточие не является семантической заменой `pass`: `pass` принято проставлять в качестве индикатора намеренного отсутствия кода, а многоточие — как напоминание TBD (to be defined) при активной разработке. Например, если соответствующий блок кода планируется добавить в следующем реквесте. ## Комментарии Однострочные комментарии начинаются с символа `#`: ```python # TODO: refactor coords calculation x = x_offset() # get x offset ``` Многострочные комментарии обрамляются тремя подряд идущими кавычками: двойными `"` либо одинарными `'`. ```python """ TODO: refactor before release! """ ``` ```python ''' TODO: refactor before release! ''' ``` PEP8 рекомендует использовать для многострочных комментариев двойные кавычки. Если многострочный комментарий следует сразу за объявлением модуля, функции, класса или метода, то он называется **docstring.** Большинство современных IDE умеют делать подсказки на основе docstring. Пример docstring для функции: ```python def get_coords(): """Here we calculate x, y and transform these coordinates to lat, lon""" pass ``` ## Резюмируем - Блоки кода определяются двоеточием и отступами. - Для обозначения отсутствия операции во вложенном блоке предусмотрен оператор `pass`. - Объект-синглтон `Ellipsis` и соответствующий ему литерал `...` имеют несколько вариантов использования. Самый частый — проставление многоточия `...` вместо `pass` для маркировки мест, где кода еще нет, но планируется его дописать. - Однострочные комментарии начинаются с символа `#`, многострочные — заключаются в тройные кавычки.
Отправка...
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!