Ситуация: мы пишем код, который будет приветствовать пришедшего на сайт и показывать, сколько уже было посетителей в этом месяце:
def sample(website="Код", visitors):
print(f"Привет, добро пожаловать в {website}! У нас более {visitors} посетителей в этом месяце.")
sample("Код", 5000000)
Но при запуске кода мы получаем ошибку:
❌ SyntaxError: non-default argument follows default argument
Что это значит: аргумент, отличный от значения по умолчанию, следует за аргументом по умолчанию. Если перевести на русский, то это значит, что мы пытаемся сделать функцию, где сначала идёт аргумент со значением по умолчанию, а потом уже обычные переменные, которые мы передаём в функцию. Но в Python сначала нужно указывать как раз обычные переменные, а только в конце — переменные со значениями по умолчанию.
Дело в том, что переменные со значениями по умолчанию — необязательные. Собственно, именно поэтому для них указывается дефолтное значение, которое используется, если мы не указали какое-то другое значение. Проще говоря, если мы их не укажем — ничего страшного, функция возьмёт для них те значения, которые мы прописали заранее.
Аргумент по умолчанию — это аргумент, который определяется знаком равенства =, за которым следует значение по умолчанию:
def sample(website, message="Привет, добро пожаловать в"):
print(message, website)
В этом примере message
— это аргумент по умолчанию со значением по умолчанию «Привет». Если не указать значение сообщения, функция будет использовать в качестве значения «Привет».
А вот если мы сначала поставим в описании функции значения по умолчанию, а потом обычные, то компьютер может запутаться: непонятно, что именно брать для каких переменных и что делать с тем, если мы укажем, например, на один аргумент меньше при вызове.
Что делать с ошибкой SyntaxError: non-default argument follows default argument
Главная причина такой ошибки — неправильный порядок аргументов. В нашем случае нужно поставить все переменные со значениями по умолчанию в самый конец объявления функции:
def sample(visitors, website="Код"):
print(f"Привет, добро пожаловать в {website}! У нас более {visitors} посетителей в этом месяце.")
sample(5000000, "Код")
Но и это можно тоже упростить, убрав второе значение при вызове, потому что оно совпадает со значением по умолчанию. Этот код даст тот же результат (обратите внимание на последнюю строку):
def sample(visitors, website="Код"):
print(f"Привет, добро пожаловать в {website}! У нас более {visitors} посетителей в этом месяце.")
sample(5000000)
Если что, значения по умолчанию в середину тоже ставить нельзя — только в самый конец при объявлении функции. Вот так — неправильно:
def calculate_total(price, quantity=10, discount):
total = price * quantity * (1 - discount)
return total
calculate_total(100, 10, 0.5)
А вот так — правильно:
def calculate_total(price, discount, quantity=10):
total = price * quantity * (1 - discount)
return total
print(calculate_total(100, 0.5, 10))