Ключевые слова — не просто часть синтаксиса, а настоящий каркас языка, определяющий его возможности и ограничения. В Python существует 35 ключевых слов и 4 так называемых "мягких ключевых слова" — термин, который многие новички даже не слышали. Что отличает их от обычных идентификаторов? Почему нельзя назвать переменную if или while ? Какие возможности дает каждое из этих слов?
Ключевые слова представляют собой зарезервированные идентификаторы, которые нельзя использовать для именования переменных, функций или классов. Они имеют строго определенное назначение и играют особую роль в синтаксисе языка. Если попытаться использовать ключевое слово в качестве имени переменной, Python немедленно выдаст ошибку SyntaxError .
Python | 1
| if = 42 # SyntaxError: invalid syntax |
|
Такое ограничение существует неспроста — ключевые слова образуют базовый словарь Python, определяющий структурные блоки кода, потоки управления и семантические конструкции языка. В отличие от функций стандартной библиотеки, ключевые слова доступны всегда, без необходимости импорта. И хотя их всего несколько десятков, они предоставляют удивительную гибкость и выразительность, делающие Python таким популярным языком программирования.
Список ключевых слов менялся на протяжении истории Python. Например, слова async и await появились лишь в Python 3.7, а match и case добавились в Python 3.10. А некоторые, такие как print и exec , существовавшие в Python 2 как ключевые слова, в Python 3 превратились в встроенные функции. Меняясь и развиваясь вместе с языком, ключевые слова отражают эволюцию Python — от простого учебного языка до мощного инструмента современной разработки. В этой статье мы подробно разберемся с каждым ключевым словом, узнаем о практических аспектах их использования и научимся избегать распространенных ошибок, связанных с ними.
Зарезервированные слова в Python
В самом сердце языка Python находятся 35 ключевых слов, образующих его синтаксический и семантический костяк. Эти зарезервированные слова нельзя использовать как имена переменных или функций – они имеют особое значение для интерпретатора. Вот полный их перечень в Python 3.12:
Python | 1
2
3
4
5
6
7
| False class from or None
True continue global pass and
as def if raise assert
async del import return await
break elif in try else
except is while finally lambda
for nonlocal with yield not |
|
Список может выглядеть внушительно, но на практике каждое из этих слов играет четко определенную роль. Давайте категоризируем их по функциональному назначению, чтобы легче было разобраться.
Ключевые слова для значений
Три ключевых слова представляют собой встроенные значения:
True и False – логические константы
None – специальное значение "ничего"
Эти значения являются синглтонами – существует только один экземпляр каждого из них в памяти программы. Когда вы пишете x = None , переменная x всегда указывает на один и тот же объект, и проверка x is None работает корректно именно благодаря этому свойству.
Python | 1
2
3
4
| # Демонстрация синглтонности None
a = None
b = None
print(a is b) # True, это один и тот же объект в памяти |
|
Операторные ключевые слова
Пять ключевых слов используются как операторы:
and , or и not – логические операторы
in – оператор проверки вхождения
is – оператор проверки идентичности объектов
Интересно, что в других языках программирования эти операции часто представлены символами: && вместо and , || вместо or , ! вместо not . Python же делает выбор в пользу читаемости, используя английские слова вместо символов.
Python | 1
2
3
4
5
6
7
8
9
10
11
12
| # Оператор "or" возвращает первый истинный операнд или последний операнд
result = "" or 0 or [] or "hello" or 42 # "hello"
# Оператор "in" проверяет вхождение элемента в последовательность
print('a' in 'abc') # True
print(4 in [1, 2, 3]) # False
# Оператор "is" проверяет, является ли левый операнд тем же объектом, что и правый
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (равны по значению)
print(a is b) # False (разные объекты в памяти) |
|
Ключевые слова для управления потоком выполнения
Значительную часть ключевых слов составляют слова для управления потоком выполнения программы:
if , elif , else – для условных конструкций
for , while – для циклов
break , continue , pass – для управления циклами
try , except , finally , raise – для обработки исключений
with , as – для контекстных менеджеров
yield – для создания генераторов
Ключевые слова для определения структур
Некоторые ключевые слова используются для определения структур в программе:
def – для определения функций
class – для определения классов
return – для возврата значения из функции
lambda – для создания анонимных функций
Python | 1
2
3
4
5
6
7
8
9
| # Использование def для определения функции
def greet(name):
return f"Hello, {name}!"
# Использование lambda для создания анонимной функции
greet_lambda = lambda name: f"Hello, {name}!"
print(greet("Alice")) # "Hello, Alice!"
print(greet_lambda("Bob")) # "Hello, Bob!" |
|
Ключевые слова для работы с модулями
Три ключевых слова используются для работы с модулями:
import – для импорта модуля
from – для импорта конкретных имен из модуля
as – для создания псевдонима при импорте
Python | 1
2
3
4
5
6
7
8
| # Импортирование всего модуля
import math
# Импортирование конкретных функций из модуля
from math import sin, cos
# Импортирование модуля с псевдонимом
import numpy as np |
|
Ключевые слова для работы с областями видимости
Несколько ключевых слов используются для работы с областями видимости переменных:
global – для объявления глобальной переменной внутри функции
nonlocal – для работы с переменными из внешней, но не глобальной области видимости
del – для удаления переменных или элементов коллекций
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Пример использования global
x = 10
def modify_global():
global x
x = 20
modify_global()
print(x) # 20, а не 10
# Пример использования nonlocal
def outer_function():
y = 10
def inner_function():
nonlocal y
y = 20
inner_function()
print(y) # 20, а не 10
outer_function() |
|
Асинхронные ключевые слова
Начиная с Python 3.5, появились ключевые слова для асинхронного программирования:
async – для определения асинхронной функции или метода
await – для ожидания результата асинхронной операции
Python | 1
2
3
4
5
6
7
8
9
10
| # Простой пример асинхронной функции
async def fetch_data():
# Имитация асинхронной операции
await asyncio.sleep(1)
return {"data": "fetched"}
# Использование await должно происходить внутри async-функции
async def process_data():
result = await fetch_data()
print(result) |
|
Сравнение с другими языками
Python, в отличие от многих других языков, делает упор на читаемость кода, его почти "естественный" вид. Сравните количество ключевых слов:- Python: 35 ключевых слов
- Java: около 50 ключевых слов
- C++: более 90 ключевых слов
- JavaScript: около 30 ключевых слов
Каждый язык имеет свои особенности. Например, в JavaScript нет ключевых слов elif или pass , а в Java отсутствует аналог Python-овского yield . В C++ много низкоуровневых ключевых слов, которых в Python просто нет ввиду его более высокого уровня абстракции.
Интересно отметить, что в разных языках одни и те же концепции могут быть выражены по-разному. Например:
1. Условие "else if" в Python выражается как elif , в JavaScript и Java как else if , а в Ruby – как elsif .
2. Для обозначения ничего/пустоты Python использует None , JavaScript – `null` и undefined , Ruby – `nil`, а Java – `null`.
3. Для определения функций Python использует def , JavaScript – `function` (или стрелочные функции), Ruby – `def`, а Java – разнообразную типизацию возвращаемых значений.
Ключевые слова Подскажите, пожалуйста, каким ключевым словом можно заменить тело функции Нету реакции на ключевые слова Есть код:
import os
import webbrowser
while True:
try:
vopros = input("Чем я могу тебе помочь?: ").lower() Прочитать файл и выдать списки, в которых есть ключевые слова a) Составьте файл, записи в котором организованы из следующих компонентов: название факультета:название кафедры; фамилия студента; код специальности.... Упорядочить ключевые слова по алфавиту, а в случае одинакового названия – по убыванию Заданы ключевые слова и номера страниц, на которых они встречаются. Необходимо упорядочить их по алфавиту, а в случае одинакового названия – по...
"Мягкие" ключевые слова в Python
Python 3.10 ввёл интересное новшество — концепцию "мягких" ключевых слов (soft keywords). В отличие от обычных ключевых слов, они ведут себя как ключевые слова только в определённых контекстах, а в других могут использоваться как обычные идентификаторы.
На данный момент в Python существует четыре мягких ключевых слова:
match и case — для конструкций структурного сопоставления образцов
_ (одиночное подчёркивание) — как специальное обозначение в структурном сопоставлении
type — для объявления алиасов типов (с Python 3.12)
Это стало возможным благодаря внедрению PEG-парсера в Python 3.9, что изменило способ анализа кода интерпретатором.
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # match и case - мягкие ключевые слова в контексте сопоставления образцов
def describe_value(value):
match value:
case 0:
return "Zero"
case int():
return "Integer"
case str():
return "String"
case _:
return "Something else"
# При этом match можно использовать как имя переменной
match = "Это строка, а не ключевое слово"
print(match) # Работает нормально!
# То же самое с case
case = 123
print(case) # И это тоже работает! |
|
Такой подход к "мягким" ключевым словам был выбран из соображений обратной совместимости. Если бы match и case стали полноценными ключевыми словами, это могло бы сломать существующий код, который уже использовал эти слова в качестве идентификаторов.
Как определить все доступные ключевые слова?
Python предоставляет удобный способ программного доступа к списку ключевых слов через модуль keyword :
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| import keyword
# Получить список всех ключевых слов
print(keyword.kwlist)
# Проверить, является ли слово ключевым
print(keyword.iskeyword("if")) # True
print(keyword.iskeyword("variable")) # False
# Получить список "мягких" ключевых слов (с Python 3.10)
print(keyword.softkwlist) # ['_', 'case', 'match', 'type']
# Проверить, является ли слово "мягким" ключевым
print(keyword.issoftkeyword("match")) # True
print(keyword.issoftkeyword("if")) # False |
|
Устаревшие ключевые слова
Интересна судьба некоторых ключевых слов, которые существовали в Python 2, но были преобразованы в функции в Python 3:
1. print — в Python 2 было ключевым словом и использовалось без скобок:
Python | 1
2
3
4
5
| # Python 2
print "Привет, мир!"
# Python 3
print("Привет, мир!") |
|
2. exec — также превратилось из ключевого слова в функцию:
Python | 1
2
3
4
5
| # Python 2
exec "x = 10"
# Python 3
exec("x = 10") |
|
Это изменение было частью улучшений в Python 3, направленных на унификацию языка и устранение исключений из общих правил.
Идентификация ключевых слов в коде
Современные IDE (интегрированные среды разработки) и редакторы кода обычно используют подсветку синтаксиса для выделения ключевых слов, что помогает визуально отличать их от переменных и других элементов кода. Это значительно упрощает чтение и понимание программ, особенно новичкам.
Управление потоком программы
Способность управлять потоком выполнения кода — одна из фундаментальных возможностей любого языка программирования. В Python для этого предусмотрен набор ключевых слов, которые позволяют создавать условные конструкции, организовывать циклы и управлять их поведением. Разберем их подробно.
Условные конструкции (if, elif, else)
Ключевое слово if — основа любой условной конструкции. С его помощью мы проверяем условие и выполняем блок кода только при истинности этого условия. Синтаксис прост и интуитивен:
Python | 1
2
| if условие:
# код выполнится только если условие истинно |
|
Python оценивает "истинность" выражений следующим образом: практически все значения считаются истинными (True ), кроме:
False
None
0 (ноль любого числового типа)
Пустые последовательности: "" , [] , () , {}
Объекты, для которых метод __bool__() или __len__() возвращает 0 или False
Вот простой пример условной конструкции:
Python | 1
2
3
4
5
6
7
8
| temperature = 22
if temperature > 25:
print("Жарко")
elif temperature > 15:
print("Комфортно")
else:
print("Холодно") |
|
Здесь ключевое слово elif (сокращение от "else if") позволяет проверить дополнительные условия, если предыдущие оказались ложными. А else указывает код, который нужно выполнить, когда ни одно из условий не сработало.
В отличие от некоторых других языков, Python не имеет конструкции switch/case (до версии 3.10), поэтому цепочки elif часто используются там, где в других языках применили бы switch .
Интересным аспектом является то, как Python обрабатывает цепочки сравнений:
Python | 1
2
3
4
5
6
| # В Python можно писать так:
if 0 < x < 10:
print("x между 0 и 10")
# В других языках пришлось бы писать так:
# if (0 < x && x < 10) { ... } |
|
Еще одна особенность Python — тернарный оператор, который использует ключевые слова if и else :
Python | 1
2
3
4
5
6
7
8
9
| # Обычная запись
message = ""
if age >= 18:
message = "Доступ разрешен"
else:
message = "Доступ запрещен"
# Тернарный оператор
message = "Доступ разрешен" if age >= 18 else "Доступ запрещен" |
|
Тернарный оператор в Python имеет необычный синтаксис по сравнению с C-подобными языками. Вместо условие ? значение_если_истина : значение_если_ложь в Python используется форма значение_если_истина if условие else значение_если_ложь .
Циклы (for, while, break, continue)
Python предоставляет два основных типа циклов:
1. Цикл while — повторяет блок кода, пока условие остаётся истинным:
Python | 1
2
3
4
5
| count = 5
while count > 0:
print(count)
count -= 1
# Выведет: 5, 4, 3, 2, 1 |
|
2. Цикл for — итерирует по последовательности (списку, строке, диапазону и т.д.):
Python | 1
2
3
| fruits = ["яблоко", "груша", "банан"]
for fruit in fruits:
print(f"У меня есть {fruit}") |
|
В отличие от многих других языков, цикл for в Python больше похож на foreach — он перебирает элементы коллекции, а не повторяет блок кода фиксированное число раз. Для числовых итераций используется встроенная функция range() :
Python | 1
2
| for i in range(5):
print(i) # Вывод: 0, 1, 2, 3, 4 |
|
Для управления поведением циклов служат ключевые слова:
break — немедленно завершает выполнение всего цикла:
Python | 1
2
3
4
| for i in range(10):
if i == 5:
break
print(i) # Выведет только 0, 1, 2, 3, 4 |
|
continue — пропускает оставшуюся часть текущей итерации и переходит к следующей:
Python | 1
2
3
4
| for i in range(5):
if i == 2:
continue
print(i) # Выведет 0, 1, 3, 4 (пропустит 2) |
|
Уникальной особенностью Python является возможность использования else с циклами. Блок else выполняется, если цикл завершился нормально (без вызова break ):
Python | 1
2
3
4
5
6
7
8
9
10
11
12
| for i in range(5):
print(i)
else:
print("Цикл завершен нормально")
# Сравните с:
for i in range(5):
if i == 3:
break
print(i)
else:
print("Это НЕ будет выполнено") |
|
Эта особенность не так широко используется, но может быть полезной в определенных сценариях, например, при поиске элементов.
Нестандартные приёмы с циклами
Первая техника — это совмещение циклов с функцией enumerate() . Она позволяет одновременно получать и индекс элемента, и сам элемент:
Python | 1
2
3
4
5
6
7
| fruits = ["яблоко", "груша", "банан"]
for index, fruit in enumerate(fruits):
print(f"{index+1}. {fruit}")
# Выведет:
# 1. яблоко
# 2. груша
# 3. банан |
|
Еще один приём — использование zip() для параллельного перебора нескольких последовательностей:
Python | 1
2
3
4
5
6
7
8
| names = ["Анна", "Борис", "Виктор"]
ages = [25, 30, 22]
for name, age in zip(names, ages):
print(f"{name} — {age} лет")
# Выведет:
# Анна — 25 лет
# Борис — 30 лет
# Виктор — 22 лет |
|
А что, если итерируемые объекты разной длины? Функция zip() остановится, когда закончится самый короткий из них. Если нужно продолжить до исчерпания самого длинного, можно использовать itertools.zip_longest() :
Python | 1
2
3
4
5
6
7
8
| from itertools import zip_longest
names = ["Анна", "Борис", "Виктор", "Галина"]
ages = [25, 30, 22]
for name, age in zip_longest(names, ages, fillvalue="неизвестно"):
print(f"{name} — {age} лет")
# Выведет:
# ...
# Галина — неизвестно лет |
|
Интересный случай — использование бесконечных циклов с явным выходом по условию:
Python | 1
2
3
4
5
6
| counter = 0
while True: # Бесконечный цикл
print(counter)
counter += 1
if counter >= 5:
break |
|
Это может показаться странным, но иногда такой подход делает код более ясным, особенно когда условия продолжения цикла сложны или могут меняться внутри тела цикла.
Ещё один нетривиальный приём — использование генераторов в циклах for . Генераторы создают значения "на лету", экономя память:
Python | 1
2
3
4
5
6
7
8
9
| # Вместо создания списка всех чисел
squares = []
for i in range(1000000):
squares.append(i*i)
# Можно использовать генератор
for square in (i*i for i in range(1000000)):
# Обработка каждого квадрата
pass |
|
Если нужно перебрать все комбинации элементов из двух или более последовательностей, пригодится itertools.product() :
Python | 1
2
3
4
5
6
| from itertools import product
suits = ['c1', 'c2', 'c3', 'c4']
ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
for rank, suit in product(ranks, suits):
print(f"{rank}{suit}", end=" ")
# Выведет все 52 карты колоды |
|
Когда речь заходит о сортировке и фильтрации, Python предлагает элегантные решения через выражения-генераторы и встроенные функции:
Python | 1
2
3
4
5
6
7
8
9
| # Фильтрация с помощью выражения-генератора
even_numbers = (x for x in range(100) if x % 2 == 0)
# То же самое с использованием filter
even_numbers = filter(lambda x: x % 2 == 0, range(100))
# Сортировка с настраиваемым ключом
sorted_words = sorted(["яблоко", "груша", "абрикос"], key=len)
# Результат: ['груша', 'яблоко', 'абрикос'] |
|
Для особо сложных случаев циклической обработки Python предоставляет мощные инструменты в модуле itertools . Например, для создания всех возможных перестановок:
Python | 1
2
3
4
5
6
7
8
9
10
| from itertools import permutations
for p in permutations([1, 2, 3]):
print(p)
# Выведет:
# (1, 2, 3)
# (1, 3, 2)
# (2, 1, 3)
# (2, 3, 1)
# (3, 1, 2)
# (3, 2, 1) |
|
Кстати, выражения-генераторы можно использовать не только в циклах, но и в функциях, которые принимают итерируемые объекты:
Python | 1
2
| # Сумма всех четных чисел от 0 до 100
total = sum(x for x in range(101) if x % 2 == 0) |
|
Используя все эти приёмы и ключевые слова, вы получаете гибкие инструменты для управления потоком вашей программы, что делает код более выразительным и лаконичным — одна из причин, почему Python так любят программисты.
Контекстный менеджер with и его применение
Среди ключевых слов Python особое место занимает with — мощный инструмент, делающий код более чистым и безопасным. Контекстный менеджер, обозначаемый ключевым словом with , автоматически управляет ресурсами, гарантируя их корректное освобождение даже при возникновении исключений. Классический пример использования контекстного менеджера — работа с файлами:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
| # Без контекстного менеджера
file = open("data.txt", "r")
try:
content = file.read()
# Обработка содержимого
finally:
file.close()
# С контекстным менеджером
with open("data.txt", "r") as file:
content = file.read()
# Обработка содержимого
# Файл автоматически закрывается при выходе из блока with |
|
Второй вариант не только короче, но и надёжнее — файл гарантированно закроется, даже если в блоке with возникнет исключение. Это предотвращает такие проблемы как утечка файловых дескрипторов.
Ключевое слово as в конструкции с with связывает результат вызова контекстного менеджера с переменной. Это позволяет использовать полученный объект внутри блока with . Контекстные менеджеры используются не только для файлов. Они востребованы во многих сценариях:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # Блокировка для многопоточных программ
import threading
lock = threading.Lock()
with lock:
# Критическая секция, защищённая блокировкой
# Подавление определённых исключений
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove("может_не_существовать.txt")
# Временное изменение рабочей директории
from contextlib import chdir
with chdir("/tmp"):
# Код, работающий в /tmp
# Автоматический возврат в предыдущую директорию |
|
Создание собственных контекстных менеджеров тоже не сложно — для этого класс должен реализовать методы __enter__ и __exit__ :
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
| class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
self.elapsed = self.end - self.start
print(f"Операция заняла {self.elapsed:.2f} секунд")
# Использование
with Timer():
time.sleep(1.5) # Выведет: "Операция заняла 1.50 секунд" |
|
Еще проще создавать контекстные менеджеры с помощью декоратора @contextmanager из модуля contextlib :
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| from contextlib import contextmanager
@contextmanager
def tempdir():
original_dir = os.getcwd()
temp_dir = tempfile.mkdtemp()
try:
os.chdir(temp_dir)
yield temp_dir
finally:
os.chdir(original_dir)
shutil.rmtree(temp_dir)
with tempdir() as path:
# Работаем во временной директории
# По завершении она будет автоматически удалена |
|
Контекстные менеджеры — настоящая жемчужина Python, демонстрирующая философию "лёгкой читаемости" кода и принцип RAII (Resource Acquisition Is Initialization).
Выражение match-case в Python 3.10+
С выходом Python 3.10 язык обогатился одной из самых долгожданных возможностей — структурным сопоставлением с образцом (pattern matching). Это механизм, реализованный с помощью конструкции match-case , которая заметно упрощает решение задач, ранее требовавших громоздких цепочек условий. Синтаксис конструкции достаточно интуитивен:
Python | 1
2
3
4
5
6
7
| match выражение:
case образец1:
# Код выполняется, если выражение соответствует образцу1
case образец2:
# Код выполняется, если выражение соответствует образцу2
case _:
# Код выполняется, если ни один из предыдущих образцов не подошёл |
|
Мягкое ключевое слово _ служит универсальным шаблоном, соответствующим абсолютно любому значению, аналогично default в классическом switch-case других языков.
Сопоставление с образцом особенно мощно при работе с составными типами данных. Вот пример анализа HTTP-ответа:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| def process_response(response):
match response:
case {"status": 200, "data": data}:
return f"Success: {data}"
case {"status": 404}:
return "Not found"
case {"status": status, "error": msg}:
return f"Error {status}: {msg}"
case _:
return "Unknown response format"
# Примеры использования
print(process_response({"status": 200, "data": "User profile"})) # Success: User profile
print(process_response({"status": 404})) # Not found
print(process_response({"status": 500, "error": "Server error"})) # Error 500: Server error |
|
Особенно хорошо выглядит работа с вложенными структурами данных. Например, можно легко анализировать JSON-ответы API:
Python | 1
2
3
4
5
6
7
8
9
10
| def process_user(user_data):
match user_data:
case {"name": name, "contacts": {"email": email}}:
return f"Пользователь {name}, email: {email}"
case {"name": name, "contacts": {"phone": phone}}:
return f"Пользователь {name}, телефон: {phone}"
case {"name": name}:
return f"Пользователь {name}, контакты неизвестны"
case _:
return "Некорректные данные пользователя" |
|
В сопоставлении с образцом встроена возможность использования "захватов" (capture patterns), когда часть образца не только проверяется на соответствие, но и присваивается переменной:
Python | 1
2
3
4
5
6
7
8
9
10
11
| command = input("Введите команду: ") # например, "открыть файл.txt"
match command.split():
case ["открыть", filename]:
print(f"Открываю файл {filename}")
case ["сохранить", filename]:
print(f"Сохраняю в файл {filename}")
case ["выход"]:
print("Завершение работы")
case _:
print("Неизвестная команда") |
|
Особенно мощным инструментом стали т.н. "защитные выражения" (guard clauses), позволяющие добавлять дополнительные условия к образцам:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
| def check_value(value):
match value:
case int(n) if n > 0:
return "Положительное целое"
case int(n) if n < 0:
return "Отрицательное целое"
case int(0):
return "Ноль"
case float(n):
return "Дробное число"
case str(s) if s.isdigit():
return "Строка с цифрами"
case _:
return "Что-то другое" |
|
Структурное сопоставление делает код более читаемым и выразительным при работе со сложными структурами данных, что раньше требовало множества вложенных условий и проверок. Это особенно полезно в приложениях, обрабатывающих данные из внешних источников, парсерах и интерпретаторах.
Стоит заметить, что хоть match-case и напоминает конструкцию switch из других языков, он гораздо мощнее благодаря способности анализировать структуру объектов, а не только сравнивать значения.
Определение функций и классов
В самом сердце Python лежат два мощных механизма структурирования кода — функции и классы. Они определяются с помощью ключевых слов def и class соответственно, и представляют собой основу для организации логики программы и абстракции данных.
Функции и ключевое слово def
Функции в Python создаются с помощью ключевого слова def , за которым следует имя функции и список параметров в скобках. Тело функции — это блок кода с отступом:
Python | 1
2
3
4
5
6
7
| def greet(name, greeting="Привет"):
"""Простая функция приветствия с документацией"""
return f"{greeting}, {name}!"
# Вызов функции
message = greet("Анна")
print(message) # Привет, Анна! |
|
Функции в Python обладают рядом интересных особенностей:
1. Документационные строки (docstrings) — многострочные комментарии в тройных кавычках, описывающие назначение функции
2. Параметры по умолчанию — как greeting="Привет" в примере выше
3. Позиционные и именованные аргументы — можно передавать аргументы по позиции или по имени
Python | 1
2
3
4
5
6
7
8
9
10
| def calculate_total(price, quantity, discount=0, tax=0.2):
subtotal = price * quantity
subtotal = subtotal - (subtotal * discount)
return subtotal * (1 + tax)
# Разные способы вызова
total1 = calculate_total(100, 2)
total2 = calculate_total(100, 2, 0.1)
total3 = calculate_total(100, 2, tax=0.1)
total4 = calculate_total(price=100, quantity=2, discount=0.15) |
|
Особенно интересны более продвинутые возможности передачи параметров:
Python | 1
2
3
4
5
6
7
8
9
10
| # Произвольное количество позиционных аргументов
def sum_all(*args):
return sum(args)
# Произвольное количество именованных аргументов
def print_user_data(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_user_data(name="Иван", age=30, city="Москва") |
|
Классы и ключевое слово class
Классы — фундамент объектно-ориентированного программирования в Python. Они определяются с помощью ключевого слова class :
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| class Person:
"""Класс, представляющий человека"""
def __init__(self, name, age):
"""Инициализация объекта"""
self.name = name
self.age = age
def greet(self):
"""Метод для приветствия"""
return f"Привет, меня зовут {self.name}!"
def celebrate_birthday(self):
"""Увеличивает возраст на 1 год"""
self.age += 1
return f"{self.name} теперь {self.age} лет!"
# Создание объекта (экземпляра) класса
person = Person("Мария", 25)
print(person.greet()) # Привет, меня зовут Мария! |
|
У классов в Python есть несколько уникальных особенностей:
1. Специальные методы — начинаются и заканчиваются двойным подчёркиванием, например, __init__ для инициализации объекта
2. Наследование — создание новых классов на основе существующих
3. Полиморфизм — возможность использовать объекты разных классов через общий интерфейс
Python | 1
2
3
4
5
6
7
8
9
| class Employee(Person): # Наследуем от класса Person
def __init__(self, name, age, position, salary):
super().__init__(name, age) # Вызываем конструктор родителя
self.position = position
self.salary = salary
def greet(self): # Переопределяем метод родителя
basic_greeting = super().greet()
return f"{basic_greeting} Я работаю как {self.position}." |
|
Ещё одна мощная возможность классов — декораторы @property и @classmethod , позволяющие создавать "умные" атрибуты и методы класса:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| class Temperature:
def __init__(self, celsius):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
@classmethod
def from_fahrenheit(cls, fahrenheit):
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
# Использование
t = Temperature(25)
print(t.fahrenheit) # 77.0
t2 = Temperature.from_fahrenheit(68)
print(t2.celsius) # 20.0 |
|
Понимание ключевых слов def и class открывает путь к созданию хорошо структурированных, поддерживаемых и расширяемых программ на Python. Эти конструкции — основа для реализации сложной логики и организации модульных систем.
Метаклассы и дескрипторы
Помимо стандартных возможностей классов и функций, Python предлагает продвинутые механизмы для тонкой настройки этих конструкций. Одними из таких механизмов являются метаклассы и дескрипторы. Метаклассы — это классы, которые создают другие классы. Они позволяют управлять процессом создания классов и модифицировать их на лету:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class MetaLogger(type):
def __new__(mcs, name, bases, namespace):
# Добавляем логирование к каждому методу класса
for key, value in namespace.items():
if callable(value) and not key.startswith('__'):
namespace[key] = log_method(value)
return super().__new__(mcs, name, bases, namespace)
def log_method(method):
def wrapper(*args, **kwargs):
print(f"Вызван метод {method.__name__}")
return method(*args, **kwargs)
return wrapper
class Product(metaclass=MetaLogger):
def calculate_price(self, quantity):
return self.price * quantity |
|
Дескрипторы — это объекты, которые определяют поведение при доступе к атрибутам класса. Они используются, например, для создания управляемых свойств:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| class Positive:
def __set_name__(self, owner, name):
self.private_name = f"_{name}"
def __get__(self, instance, owner):
return getattr(instance, self.private_name)
def __set__(self, instance, value):
if value <= 0:
raise ValueError("Значение должно быть положительным")
setattr(instance, self.private_name, value)
class Product:
price = Positive()
quantity = Positive()
def __init__(self, price, quantity):
self.price = price
self.quantity = quantity |
|
Эти продвинутые механизмы активно используются в фреймворках и библиотеках для реализации магии "из коробки" и делают Python невероятно гибким языком программирования.
Асинхронное программирование с async и await
С появлением Python 3.5 в язык были добавлены ключевые слова async и await , открывшие новую эру в асинхронном программировании. Эти ключевые слова позволяют писать конкурентный код, который эффективно обрабатывает операции ввода-вывода без блокировки основного потока выполнения. Ключевое слово async используется для определения асинхронных функций, также известных как корутины:
Python | 1
2
3
4
5
| async def fetch_data(url):
"""Асинхронная функция для получения данных по URL"""
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json() |
|
Внутри асинхронной функции мы используем ключевое слово await для ожидания завершения других асинхронных операций. Важно понимать, что await можно использовать только внутри функций, объявленных как async .
Когда интерпретатор встречает await , он приостанавливает выполнение текущей корутины до тех пор, пока ожидаемая операция не будет завершена, но при этом не блокирует поток выполнения — другие корутины могут продолжать работать:
Python | 1
2
3
4
5
6
| async def main():
task1 = fetch_data("https://api.example.com/data1")
task2 = fetch_data("https://api.example.com/data2")
# Запускаем обе задачи параллельно
results = await asyncio.gather(task1, task2)
print(f"Получено {len(results)} результатов") |
|
Для запуска асинхронных функций необходимо использовать цикл событий asyncio:
Python | 1
2
3
| if __name__ == "__main__":
import asyncio
asyncio.run(main()) |
|
Преимущества асинхронного подхода особенно заметны в задачах с интенсивным вводом-выводом, таких как сетевые запросы или операции с файлами. Например, вместо последовательного выполнения 100 HTTP-запросов, которое может занять минуты, асинхронный код выполнит те же запросы за секунды.
Асинхронные функции также могут использоваться в классах — для этого методы объявляются с ключевым словом async :
Python | 1
2
3
4
5
6
7
8
9
| class DataFetcher:
def __init__(self, base_url):
self.base_url = base_url
async def fetch_item(self, item_id):
url = f"{self.base_url}/{item_id}"
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json() |
|
Важно понимать, что асинхронное программирование не делает код многопоточным или многопроцессным — вместо этого оно использует концепцию конкурентного выполнения в рамках одного потока, что делает его легковесным и эффективным для многих типов задач.
Область видимости и ключевое слово nonlocal
Понимание области видимости переменных критично для эффективного программирования на Python. В этом языке действует правило LEGB (Local, Enclosing, Global, Built-in), определяющее порядок поиска имён переменных в различных областях видимости. Ключевое слово nonlocal решает специфическую проблему доступа к переменным из охватывающей (enclosing) области видимости. Рассмотрим пример без использования nonlocal :
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
| def outer_function():
count = 0
def inner_function():
# Мы можем читать значение count, но не можем изменять его
print(f"Текущее значение count: {count}")
# count += 1 # Это вызовет UnboundLocalError
inner_function()
count += 1
return count
print(outer_function()) # 1 |
|
Проблема в том, что внутренняя функция может читать значение переменной из внешней области, но не может его изменять. Именно здесь приходит на помощь ключевое слово nonlocal :
Python | 1
2
3
4
5
6
7
8
9
10
11
12
| def outer_function():
count = 0
def inner_function():
nonlocal count # Объявляем, что хотим использовать count из внешней функции
print(f"Текущее значение count: {count}")
count += 1 # Теперь это работает корректно
inner_function()
return count
print(outer_function()) # 1 |
|
Это особенно полезно при создании замыканий (closures) — функций, захватывающих состояние из своего окружения. Например, простой счётчик:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
| def create_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
my_counter = create_counter()
print(my_counter()) # 1
print(my_counter()) # 2 |
|
Важно отметить: nonlocal не может использоваться для доступа к глобальным переменным (для этого есть global ) и не может создавать новые переменные в охватывающей области — эта переменная должна уже существовать.
Обработка ошибок
Обработка ошибок — важнейшая часть программирования на любом языке. Python предлагает элегантный и выразительный механизм обработки исключений с помощью нескольких ключевых слов: try , except , finally , raise и else . Ключевое слово try обозначает блок кода, в котором могут возникнуть исключения. За ним следует один или несколько блоков except , определяющих реакцию на конкретные типы исключений:
Python | 1
2
3
4
5
6
7
8
| try:
number = int(input("Введите число: "))
result = 100 / number
print(f"Результат: {result}")
except ValueError:
print("Вы ввели не число!")
except ZeroDivisionError:
print("На ноль делить нельзя!") |
|
В этом примере мы обрабатываем два различных типа исключений: ValueError возникает при попытке преобразовать нечисловую строку в число, а ZeroDivisionError — при делении на ноль. Если нужно обработать сразу несколько типов исключений одинаково, их можно объединить в кортеж:
Python | 1
2
3
4
5
| try:
# код, который может вызвать исключение
pass
except (ValueError, TypeError, KeyError):
print("Произошла одна из нескольких возможных ошибок") |
|
Мы также можем получить доступ к объекту исключения, что полезно для извлечения дополнительной информации:
Python | 1
2
3
4
5
6
| try:
with open("несуществующий_файл.txt") as file:
content = file.read()
except FileNotFoundError as e:
print(f"Ошибка: {e}")
# Можем использовать e.filename, e.strerror и другие атрибуты |
|
Ключевое слово finally определяет блок, который выполняется всегда — независимо от того, произошло исключение или нет. Это идеальное место для освобождения ресурсов:
Python | 1
2
3
4
5
6
7
8
| try:
file = open("data.txt", "r")
# работа с файлом
except FileNotFoundError:
print("Файл не найден")
finally:
# Этот блок выполнится в любом случае
file.close() if 'file' in locals() else None |
|
Впрочем, для работы с файлами лучше использовать контекстный менеджер with , который автоматически закрывает файл.
Блок else в обработке исключений может показаться необычным: он выполняется только если в блоке try не возникло исключений. Это полезно для разделения "нормального" кода от обработки ошибок:
Python | 1
2
3
4
5
6
7
| try:
data = json.loads(json_string)
except json.JSONDecodeError:
print("Некорректный JSON")
else:
# Этот код выполнится только если JSON был успешно разобран
process_data(data) |
|
Ключевое слово raise позволяет программисту явно вызвать исключение:
Python | 1
2
3
4
5
6
| def validate_age(age):
if age < 0:
raise ValueError("Возраст не может быть отрицательным")
if age > 120:
raise ValueError("Возраст слишком большой")
return age |
|
Интересный приём — повторный вызов исключения после его обработки:
Python | 1
2
3
4
5
| try:
risky_operation()
except Exception as e:
log_error(e) # Логируем ошибку
raise # Пробрасываем исключение дальше |
|
В Python 3.11 появилась новая возможность — группы исключений и оператор except* :
Python | 1
2
3
4
5
| try:
complicated_operation()
except* (NetworkError, DatabaseError) as e:
# Обрабатываем группу связанных исключений
handle_system_errors(e) |
|
Ключевое слово assert используется для проверок в процессе разработки. Оно вызывает AssertionError , если условие ложно:
Python | 1
2
3
| def calculate_average(numbers):
assert len(numbers) > 0, "Пустой список"
return sum(numbers) / len(numbers) |
|
Важно помнить, что утверждения (assert ) могут быть отключены при запуске Python с оптимизацией (-O ), поэтому их не стоит использовать для проверок, критичных для безопасности.
Грамотная обработка ошибок делает программы более надежными и предсказуемыми. Вместо аварийного завершения программист может предусмотреть реакцию на различные исключительные ситуации, что особенно ценно в продакшн-системах.
Создание собственных исключений
Python позволяет не только обрабатывать встроенные исключения, но и создавать собственные типы исключений. Это особенно полезно при разработке библиотек, фреймворков или сложных приложений, где требуется более точно классифицировать ошибки. Создать собственное исключение очень просто — достаточно унаследовать класс от базового класса Exception или любого его подкласса:
Python | 1
2
3
| class InsufficientFundsError(Exception):
"""Вызывается при попытке снять со счёта больше денег, чем на нём есть."""
pass |
|
Даже такое минимальное определение уже функционально. Можно использовать это исключение в коде:
Python | 1
2
3
4
5
| def withdraw(account, amount):
if amount > account.balance:
raise InsufficientFundsError("Недостаточно средств на счёте")
account.balance -= amount
return amount |
|
Для более сложных случаев можно расширить функциональность исключения, добавив дополнительные атрибуты и методы:
Python | 1
2
3
4
5
6
7
8
9
10
11
| class ValidationError(Exception):
def __init__(self, field, message):
self.field = field
self.message = message
super().__init__(f"Ошибка валидации поля '{field}': {message}")
# Использование
def validate_user(user_data):
if len(user_data.get('username', '')) < 3:
raise ValidationError('username', 'Имя пользователя должно содержать не менее 3 символов')
# Остальные проверки... |
|
При создании иерархии исключений для сложной библиотеки или приложения полезно определить базовый класс исключений для вашего проекта:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| class AppError(Exception):
"""Базовый класс для всех исключений приложения."""
pass
class DatabaseError(AppError):
"""Ошибки, связанные с базой данных."""
pass
class NetworkError(AppError):
"""Ошибки сетевого взаимодействия."""
pass
class ValidationError(AppError):
"""Ошибки валидации данных."""
pass |
|
Такая структура делает код более читабельным и облегчает обработку исключений:
Python | 1
2
3
4
5
6
7
8
9
10
11
| try:
result = complex_operation()
except DatabaseError:
# Обработка проблем с БД
rollback_transaction()
except NetworkError as e:
# Обработка сетевых проблем
retry_connection(e.connection_info)
except AppError:
# Обработка любых других ошибок приложения
log_application_error() |
|
При создании собственных исключений придерживайтесь нескольких простых правил:
1. Давайте классам исключений имена, заканчивающиеся на "Error" или "Exception"
2. Не создавайте слишком много уровней наследования
3. Документируйте ваши исключения, объясняя, когда и почему они возникают
4. По возможности включайте в исключения информацию, полезную для отладки
Собственные исключения — это не просто способ сообщить об ошибке, но и мощный инструмент для создания четкого API вашего кода, который делает взаимодействие с ним более предсказуемым и понятным.
Практические советы
Работа с ключевыми словами Python требует не только понимания их синтаксиса, но и правильного применения на практике. Давайте рассмотрим некоторые распространённые ошибки новичков и приёмы, которые используют опытные разработчики.
Частые ошибки новичков
Одна из самых распространённых проблем — неправильная проверка на равенство с использованием is вместо == :
Python | 1
2
3
4
5
6
7
| # Неправильно
if x is 10: # Работает случайно только для некоторых целых чисел из-за интернирования
print("x равно 10")
# Правильно
if x == 10:
print("x равно 10") |
|
Оператор is проверяет идентичность объектов, а не равенство значений. Используйте его только для проверки на None , True , False или идентичность объектов.
Другая распространённая ошибка — создание изменяемого значения по умолчанию в функции:
Python | 1
2
3
4
5
6
7
8
9
10
11
| # Неправильно
def add_item(item, items=[]): # Список создаётся только один раз при определении функции!
items.append(item)
return items
# Правильно
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items |
|
Начинающие разработчики также часто пропускают блоки finally и забывают о его важности для корректного освобождения ресурсов:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Неправильно (есть риск утечки ресурсов)
def process_file(filename):
try:
file = open(filename)
return file.read()
except FileNotFoundError:
return None
# Правильно
def process_file(filename):
file = None
try:
file = open(filename)
return file.read()
except FileNotFoundError:
return None
finally:
if file is not None:
file.close() |
|
Впрочем, в этом конкретном примере ещё лучшим решением было бы использование контекстного менеджера with .
Приёмы опытных разработчиков
Профессионалы Python часто используют ключевое слово or для установки значений по умолчанию:
Python | 1
2
| # Краткий способ установить значение по умолчанию
name = user_input or "Гость" # Если user_input пустой, используется "Гость" |
|
Опытные программисты активно применяют выражение-генератор вместо списковых включений, когда не нужно хранить все результаты в памяти:
Python | 1
2
3
4
5
| # Вместо этого (создаёт список в памяти):
total = sum([x*2 for x in range(1000000)])
# Используйте это (генерирует значения на лету):
total = sum(x*2 for x in range(1000000)) |
|
Для работы с контекстными менеджерами профессионалы часто комбинируют несколько вызовов with с помощью запятой:
Python | 1
2
3
4
5
6
7
8
| # Вместо вложенных with
with open('input.txt') as in_file:
with open('output.txt', 'w') as out_file:
out_file.write(in_file.read())
# Используйте это
with open('input.txt') as in_file, open('output.txt', 'w') as out_file:
out_file.write(in_file.read()) |
|
Многие опытные программисты стараются максимально избегать глобальных переменных (global ) и предпочитают явно передавать значения через параметры функций, что делает код более тестируемым и поддерживаемым.
Также профессионалы активно используют атрибут __slots__ в классах для экономии памяти и повышения производительности:
Python | 1
2
3
4
5
6
| class Point:
__slots__ = ('x', 'y') # Ограничивает набор атрибутов и экономит память
def __init__(self, x, y):
self.x = x
self.y = y |
|
Эти приёмы и избегание распространённых ошибок помогут вам писать более элегантный, эффективный и надёжный код на Python.
Оптимизация кода с учетом особенностей работы ключевых слов
Понимание внутренних механизмов работы ключевых слов Python позволяет писать более оптимизированный код. Рассмотрим несколько техник, которые помогают повысить производительность программ с учетом особенностей языка.
Оптимизация циклов и условий
При работе с циклами, особенно с большими наборами данных, стоит избегать лишних проверок и вычислений:
Python | 1
2
3
4
5
6
7
8
| # Неоптимальный подход
for i in range(len(my_list)):
item = my_list[i] # Двойная индексация
# Работа с item
# Оптимизированный вариант
for item in my_list:
# Прямая работа с item |
|
Для условных конструкций полезно использовать приоритизацию условий — размещать наиболее вероятные или наименее ресурсоемкие проверки первыми:
Python | 1
2
3
4
5
6
7
| # Менее эффективно
if complex_calculation() and x > 0:
# Действия
# Более эффективно
if x > 0 and complex_calculation():
# Действия |
|
Ключевое слово break позволяет существенно ускорить выполнение циклов, когда цель уже достигнута:
Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
| # Полный перебор
found = False
for item in large_collection:
if matches_criteria(item):
found = True
[H2]Использование found после цикла[/H2]
# Оптимизированный вариант
found = False
for item in large_collection:
if matches_criteria(item):
found = True
break |
|
Оптимизация импортов
Импорты в Python имеют свою стоимость. Размещение импортов внутри функций — эффективный приём, когда модули используются редко:
Python | 1
2
3
4
| def rare_operation():
# Импорт только при вызове функции
import heavy_module
return heavy_module.process() |
|
Также стоит избегать импорта с использованием звездочки (from module import * ), поскольку это засоряет пространство имен и может приводить к неожиданным конфликтам.
Оптимизация обработки исключений
Блоки try-except имеют некоторые накладные расходы. Следует избегать использования исключений для контроля нормального потока выполнения программы:
Python | 1
2
3
4
5
6
7
8
| # Неоптимально
try:
value = my_dict[key]
except KeyError:
value = default_value
# Более эффективно
value = my_dict.get(key, default_value) |
|
Ключевое слово global
Использование global замедляет доступ к переменным, поскольку Python должен искать их в глобальном пространстве имен. По возможности передавайте параметры явно:
Python | 1
2
3
4
5
6
7
8
9
10
11
| # Медленнее
counter = 0
def increment():
global counter
counter += 1
# Быстрее
counter = 0
def increment(c):
return c + 1
counter = increment(counter) |
|
Оптимизация функций
При создании функций с ключевым словом def используйте аннотации типов для лучшей читаемости и возможности статического анализа:
Python | 1
2
| def calculate_average(numbers: list[float]) -> float:
return sum(numbers) / len(numbers) |
|
Для часто вызываемых небольших функций рассмотрите возможность использования lambda , но помните о балансе между производительностью и читаемостью.
При правильном понимании особенностей работы ключевых слов Python можно значительно оптимизировать код, сделав его не только более эффективным, но и более читабельным и поддерживаемым.
Удалить все строки, где встречаются заданные ключевые слова, из большого текстового файла Есть log-файл на несколько гигабайт, нужно удалить из него все строки, в которых встречаются ключевые слова из заданного списка. Решение в целом... Не получается установить python так чтобы в терминале можно было писать команды начиная из слова "python" Здравствуйте, не получается установить python так чтобы в терминале можно было писать команды начиная из слова python.
Checkbox add python to path... Странные слова (Python) Ученикам, желающим запомнить правила написания слов в английском языке, часто напоминают следующее рифмованное одностишие: «I before E except after... Повторяющиеся слова в csv python Есть задание "Повторяющиеся слова в csv python"...нашел на форуме такое же задание один в один решение для него, именно то что надо. Но почему то КОД... Вывести слова с списка в Python'e Здраствуйте!Подскажите как вывести отсюда слова, которые начинаються на букву "B"
Заранее благодарна!
ls =
for i in range(0, len(ls),... Игра в слова в телеграмм боте на Python @bot.message_handler(commands=)
def start_message(message):
keyboard = telebot.types.InlineKeyboardMarkup()
keyboard_cities =... Игра в слова в телеграмм боте на Python @bot.message_handler(commands=)
def start_message(message):
keyboard = telebot.types.InlineKeyboardMarkup()
keyboard_cities =... Поиск и замена слова в документе через python-docx Привет. Как с помощью python-docx выполнить поиск определенного слова с последующей заменой? Документацию прочел, но так и не нашел соответствующей... Найти длину самого короткого слова в строке (python 3.x) Найти длину самого короткого слова в задаваемой строке, ЖЕЛАТЕЛЬНО используя тему методов работы со строками и списками (без задания функций и т.д) Завтра сдавать, задача на Python генератор, поиск числа и преобразование в слова Условие:
Написать программу которая читая символы из бесконечной последовательности(эмулируется конечным файлом, читающимся поблочно), распознает... Написать программу на python, которая считает размер самого первого слова в файле Нужно создать модуль, который будет считать размер самого первого слова в файле. Вывести на экран все слова, отличные от последнего слова, предварительно удалив из каждого слова последнюю букву Программа. Данная последовательность, содержащая от 2 до 15 слов, в каждом из которых от 2
до 10 латинских букв; между соседними словами - не менее...
|