Python привлекает тем, что код на нём читается почти как обычный текст: меньше скобок, меньше церемоний, больше смысла на строку. Но за этой простотой стоят несколько решений языка, которые лучше понять сразу — иначе легко словить неожиданное поведение. Разберём базовый синтаксис и систему типов с самого начала.
Отступы — это блоки кода
В большинстве языков блок кода выделяют фигурными скобками. В Python блок задаётся отступом — обычно четыре пробела. Двоеточие в конце строки открывает новый блок, а возврат на прежний уровень отступа его закрывает.
def greet(name):
if name: # двоеточие открывает блок
print(f"Привет, {name}") # этот код внутри if
else:
print("Привет, гость")
print("Готово") # снова уровень функции, вне if/else
Из этого следует простое правило: отступы — не косметика, а синтаксис. Сместил строку на пробел — изменил смысл программы или получил ошибку. Не смешивай пробелы и табы; общепринятый стиль — четыре пробела.
Переменные и динамическая типизация
Переменную не нужно объявлять заранее и указывать её тип — достаточно присвоить значение. Тип определяется в момент присваивания и может меняться по ходу программы. Это и есть динамическая типизация.
x = 42 # сейчас x — целое число
x = "сорок" # а теперь та же переменная ссылается на строку
Важно понимать, что переменная в Python — это не «коробка со значением», а имя, привязанное к объекту. Присваивание не копирует значение, а перенаправляет имя на другой объект. Узнать тип текущего значения можно функцией type:
n = 42
print(type(n)) # <class 'int'>
Динамическая типизация удобна для быстрой разработки, но за ней легко не заметить ошибку: переменная незаметно стала не тем, чем вы ожидали. Поэтому в серьёзных проектах добавляют подсказки типов (об этом — в отдельной статье).
Базовые типы
Минимальный набор, с которого всё начинается:
age = 30 # int — целое число произвольной длины
price = 19.99 # float — число с плавающей точкой
name = "Анна" # str — строка (текст в кавычках)
active = True # bool — логический тип: True или False
nothing = None # None — «значения нет»
Несколько деталей, которые экономят время:
intне имеет фиксированного предела разрядности — большие числа не переполняются, Python расширяет их автоматически.float— это та же двоичная плавающая точка, что и везде, со всеми её сюрпризами:0.1 + 0.2даст0.30000000000000004, а не ровно0.3. Для денег используют типDecimalиз модуляdecimal.boolна самом деле подвидint:Trueравен1,Falseравен0. ПоэтомуTrue + Trueвернёт2(так делать не стоит, но знать полезно).None— единственное значение типаNoneType, означает «здесь ничего нет». Сравнивают с ним черезis:if value is None.
f-строки: подстановка значений в текст
Самый удобный способ собрать строку из значений — f-строка: буква f перед кавычками включает подстановку выражений в фигурных скобках.
name = "Анна"
age = 30
print(f"{name}, возраст {age}") # Анна, возраст 30
print(f"Через год будет {age + 1}") # выражение тоже работает
print(f"Цена: {price:.2f}") # форматирование: 19.99
Внутри {} можно писать любое выражение, а после двоеточия — спецификатор формата (например, :.2f — два знака после точки). f-строки читаемее и быстрее, чем старая конкатенация через + или метод format.
Операторы
Арифметика выглядит привычно, но есть пара особенностей:
print(7 / 2) # 3.5 — обычное деление всегда даёт float
print(7 // 2) # 3 — целочисленное деление (отбрасывает дробь)
print(7 % 2) # 1 — остаток от деления
print(2 ** 10) # 1024 — возведение в степень
Сравнения возвращают bool и их можно связывать в цепочку, как в математике:
x = 5
print(0 < x < 10) # True — то же, что 0 < x and x < 10
Логические операторы пишутся словами: and, or, not. А оператор == сравнивает значения, тогда как is — это тот же самый объект в памяти. Для чисел и строк почти всегда нужен ==; is используют только с None.
Управляющие конструкции
Ветвления и циклы тоже опираются на отступы и двоеточие.
score = 75
if score >= 90:
grade = "отлично"
elif score >= 60: # elif — это «else if»
grade = "нормально"
else:
grade = "слабо"
Цикл for в Python перебирает элементы последовательности, а не считает индексы. Чтобы пройтись по диапазону чисел, берут range:
for i in range(3): # 0, 1, 2
print(i)
for letter in "abc": # строку тоже можно перебирать
print(letter)
Цикл while повторяет блок, пока условие истинно. Управляют циклами break (выйти) и continue (перейти к следующей итерации):
n = 0
while True:
n += 1
if n == 3:
continue # пропустить остаток итерации
if n > 5:
break # выйти из цикла
print(n) # 1, 2, 4, 5
Всё в Python — объект
Ключевая идея языка: любое значение — это объект. Число, строка, функция, даже сам тип — у всего есть свой тип, свои методы и идентичность. Это значит, что функцию можно положить в переменную, передать в другую функцию или вернуть из неё.
def shout(text):
return text.upper()
f = shout # функция — обычный объект, кладём в переменную
print(f("привет")) # ПРИВЕТ
Из этого же следует, что у строки или числа есть методы: "abc".upper(), (-5).__abs__(). Единообразие «всё — объект» делает язык предсказуемым: новые сущности ведут себя по тем же правилам, что и встроенные.
Изменяемые и неизменяемые типы
Это одно из самых важных различий, которое стоит усвоить сразу. Объекты бывают неизменяемые (immutable) — их нельзя поменять после создания, и изменяемые (mutable) — их содержимое можно править на месте.
- Неизменяемые:
int,float,bool,str,tuple,None. - Изменяемые:
list,dict,set.
Что значит «нельзя поменять» для строки? Любая операция над ней создаёт новый объект, а старый остаётся нетронутым:
s = "abc"
s2 = s.upper() # создаётся новая строка "ABC"
print(s) # abc — исходная строка не изменилась
А список меняется на месте, и это легко приводит к неожиданностям, когда на один объект ссылаются два имени:
a = [1, 2, 3]
b = a # b и a — это одно имя одного списка
b.append(4)
print(a) # [1, 2, 3, 4] — изменился и a, ведь объект один
Короткая формула: присваивание копирует ссылку, а не объект. Если нужен независимый список, делают копию явно: b = a.copy() или b = list(a).
Отсюда же — частая ловушка новичка: нельзя использовать изменяемый объект как значение по умолчанию у параметра функции (def f(items=[])), потому что этот список создаётся один раз и сохраняется между вызовами. Подробнее об этом — в статье о функциях.
Коротко
- Блоки кода задаются отступами (4 пробела) и двоеточием, а не скобками — отступ это синтаксис.
- Типизация динамическая: тип привязан к значению, а переменная — это имя-ссылка на объект.
- Базовые типы:
int(без предела разрядности),float(двоичный, неточный для дробей),str,bool(подвидint),None. - f-строки (
f"{value}") — основной способ собирать текст из значений. /всегда даётfloat,//— целочисленное деление;==сравнивает значения,is— идентичность (нужен дляNone).- Всё — объект: функции, типы и числа можно хранить в переменных и передавать.
- Делите типы на неизменяемые (
int,str,tuple) и изменяемые (list,dict,set); присваивание копирует ссылку, а не объект.
Что почитать дальше
- Структуры данных Python — списки, словари, множества и кортежи подробно.
- Функции и модули — как объявлять функции, аргументы по умолчанию и организация кода.
- Инструментарий разработчика — окружения, пакеты и проверка типов на практике.