Positional argument follows keyword argument python ошибка

Одна ошибка, с которой вы можете столкнуться в Python: SyntaxError : positional argument follows keyword argument Эта ошибка возникает, когда вы используете позиционный аргумент в функции после использования аргумента ключевого слова . Вот разница между ними: Позиционные аргументы — это аргументы, перед которыми нет «ключевого слова». * Пример: my_function (2, 2) Аргументы ключевых слов — это аргументы , перед которыми стоит «ключевое слово». * Пример: my_function(a=2, b=2) Если вы ис
  • Редакция Кодкампа

17 авг. 2022 г.
читать 1 мин


Одна ошибка, с которой вы можете столкнуться в Python:

SyntaxError : positional argument follows keyword argument

Эта ошибка возникает, когда вы используете позиционный аргумент в функции после использования аргумента ключевого слова .

Вот разница между ними:

Позиционные аргументы — это аргументы, перед которыми нет «ключевого слова».

  • Пример: my_function (2, 2)

Аргументы ключевых слов — это аргументы , перед которыми стоит «ключевое слово».

  • Пример: my_function(a=2, b=2)

Если вы используете позиционный аргумент после аргумента ключевого слова, Python выдаст ошибку.

  • Пример: my_function(a=2, 2)

В следующем примере показано, как эта ошибка может возникнуть на практике.

Пример: Аргумент позиции следует за аргументом ключевого слова

Предположим, у нас есть следующая функция в Python, которая умножает два значения, а затем делит на третье:

def do_stuff (a, b):
 return a * b / c

В следующих примерах показаны допустимые и недопустимые способы использования этой функции:

Правильный способ №1: все позиционные аргументы

Следующий код показывает, как использовать нашу функцию со всеми позиционными аргументами:

do_stuff( 4 , 10 , 5 )

8.0

Никакой ошибки не возникает, потому что Python точно знает, какие значения использовать для каждого аргумента в функции.

Верный способ № 2: все аргументы ключевых слов

Следующий код показывает, как использовать нашу функцию со всеми аргументами ключевого слова:

do_stuff(a= 4 , b= 10 , c= 5 )

8.0

И снова ошибка не возникает, потому что Python точно знает, какие значения использовать для каждого аргумента в функции.

Действенный способ № 3: позиционные аргументы перед ключевыми аргументами

Следующий код показывает, как использовать нашу функцию с позиционными аргументами, используемыми перед аргументами ключевого слова:

do_stuff(4, b=10, c=5)

8.0

Никакой ошибки не возникает, потому что Python знает, что аргументу a должно быть присвоено значение 4 .

Неверный способ: позиционные аргументы после аргументов ключевого слова

Следующий код показывает, как мы можем попытаться использовать функцию с позиционными аргументами, используемыми после аргументов ключевого слова:

do_stuff(a= 4, 10, 5)

SyntaxError : positional argument follows keyword argument

Возникает ошибка, потому что мы использовали позиционные аргументы после аргументов ключевого слова.

В частности, Python не знает, следует ли присваивать значения 10 и 5 аргументам b или c , поэтому он не может выполнить функцию.

Дополнительные ресурсы

В следующих руководствах объясняется, как исправить другие распространенные ошибки в Python:

Как исправить KeyError в Pandas
Как исправить: ValueError: невозможно преобразовать число с плавающей запятой NaN в целое число
Как исправить: ValueError: операнды не могли транслироваться вместе с фигурами

In this article, we will discuss how to fix the syntax error that is positional argument follows keyword argument in Python

An argument is a value provided to a function when you call that function. For example, look at the below program –

Python

def calculate_square(num):

    return num * num

result = calculate_square(10)

print(result)

The calculate_square() function takes in an argument num which is an integer or decimal input, calculates the square of the number and returns the value.

Keyword and Positional Arguments in Python

There are two kind of arguments, namely, keyword and positional. As the name suggests, the keyword argument is identified by a function based on some key whereas the positional argument is identified based on its position in the function definition. Let us have a look at this with an example.

Python

def foo(a, b, c=10):

    print('a =', a)

    print('b =', b)

    print('c =', c)

print("Function Call 1")

foo(2, 3, 8)

print("Function Call 2")

foo(2, 3)

print("Function Call 3")

foo(a=2, c=3, b=10)

Output:

Function Call 1
a = 2
b = 3
c = 8
Function Call 2
a = 2
b = 3
c = 10
Function Call 3
a = 2
b = 10
c = 3

Explanation:

  1. During the first function call, we provided 3 arguments with any keyword. Python interpreted in order of how they have been defined in the function that is considering position of these keywords.
  2. In the second function call, we provided 2 arguments, but still the output is shown because of we provided 2 positional argument and the function has a default value for the final argument c. So, it takes the default value into account for the final argument.
  3. In the third function call, three keyword arguments are provided. The benefit of providing this keyword argument is that you need not remember the positions but just the keywords that are required for the function call. These keywords can be provided in any order but function will take these as key-value pairs and not in the order which they are being passed.

SyntaxError: positional argument follows keyword argument

In the above 3 cases, we have seen how python can interpret the argument values that are being passed during a function call. Now, let us consider the below example which leads to a SyntaxError.

Python

def foo(a, b, c=10):

    print('a =', a)

    print('b =', b)

    print('c =', c)

print("Function Call 4")

foo(a=2, c=3, 9)

Output:

File "<ipython-input-40-982df054f26b>", line 7
    foo(a=2, c=3, 9)
                 ^
SyntaxError: positional argument follows keyword argument

Explanation:

In this example, the error occurred because of the way we have passed the arguments during the function call. The error positional argument follows keyword argument means that the if any keyword argument is used in the function call then it should always be followed by keyword arguments. Positional arguments can be written in the beginning before any keyword argument is passed. Here, a=2 and c=3 are keyword argument. The 3rd argument 9 is a positional argument. This can not be interpreted by the python as to which key holds what value. The way python works in this regards is that, it will first map the positional argument and then any keyword argument if present.

How to avoid the error – Conclusion

Table of Contents
Hide
  1. What is SyntaxError: positional argument follows keyword argument?
  2. How to fix SyntaxError: positional argument follows keyword argument?
    1. Scenario 1 – Use only Positional Arguments.
    2. Scenario 2 – Use only Keyword Arguments.
    3. Scenario 3 – Use Positional arguments first, followed by Keyword Arguments.
  3. Conclusion

If you provide the keyword argument first followed by a positional argument, the Python interpreter will raise SyntaxError: positional argument follows keyword argument.

In this tutorial, we will learn what SyntaxError: positional argument follows keyword argument means and how to resolve this error with examples.

An argument is a variable, value, or object passed to a method or function as an input. We have two types of arguments in Python, and we can pass these arguments while calling the methods.

Positional Argument -The positional arguments are the one that does not have any keyword in front of them.

Example

result = add_numbers(10, 20, 30)

Keyword Argument -The Keyword arguments are the one that has a keyword in front of them.

Example

result = add_numbers(a=10, b=20, c=30)

Every programming language has its own set of rules. These rules are referred to as the syntax that needs to be followed while programming.

The positional and keyword arguments must appear in a specific order; otherwise, the Python interpreter will throw a Syntax error.

The Python rule says positional arguments must appear first, followed by the keyword arguments if we are using it together to call the method.

The SyntaxError: positional argument follows keyword argument means we have failed to follow the rules of Python while writing a code.

Let us take a simple example to demonstrate this error.

# Method that takes 3 arguments and returns sum of it
def add_numbers(a, b, c):
    return a+b+c

# call the method by passing the arguments
result = add_numbers(a=10, 20, 30)

# print the output
print("Addition of numbers is", result)

Output

  File "c:PersonalIJSCodemain.py", line 8
    result = add_numbers(a=10, 20, 30)
                                     ^
SyntaxError: positional argument follows keyword argument

We have passed the Keyword argument first in the above code and then followed by the Positional argument which breaks the rule and hence we get the SyntaxError.

How to fix SyntaxError: positional argument follows keyword argument?

There are several ways to fix the error. Let us look at all the correct ways to call the methods in Python.

Scenario 1 – Use only Positional Arguments.

The easier way to fix the issue is to use only Positional arguments while calling the method in Python.

Let us fix our example by passing only positional arguments and see what happens when we run the code.

# Method that takes 3 arguments and returns sum of it
def add_numbers(a, b, c):
    return a+b+c

# call the method by passing only positional arguments
result = add_numbers(10, 20, 30)

# print the output
print("Addition of numbers is", result)

Output

Addition of numbers is 60

The code runs without any error as Python knows which values to use for each argument in the function.

Scenario 2 – Use only Keyword Arguments.

Another way to resolve the error is to use only the Keyword arguments while calling the method in Python.

# Method that takes 3 arguments and returns sum of it
def add_numbers(a, b, c):
    return a+b+c


# call the method by passing only keyword arguments
result = add_numbers(a=10, b=20, c=30)

# print the output
print("Addition of numbers is", result)

Output

Addition of numbers is 60

The code runs without any error as Python knows which values to use for each argument in the function.

Scenario 3 – Use Positional arguments first, followed by Keyword Arguments.

If you need to use both positional and keyword arguments, you need to abide by the rules of Python.

The Positional arguments should always appear first, followed by the keyword arguments.

In the below example, we have fixed the issue by passing the two positional arguments first and then a keyword argument.

# Method that takes 3 arguments and returns sum of it
def add_numbers(a, b, c):
    return a+b+c


# pass all positional arguments first and then keyword arguments
result = add_numbers(10, 20, c=30)

# print the output
print("Addition of numbers is", result)

Output

Addition of numbers is 60

Conclusion

In Python, the SyntaxError: positional argument follows keyword argument occurs if you pass keyword arguments before the positional arguments. Since Python interprets positional arguments in the order in which they appear first and then followed by the keyword arguments as next.

We can resolve the SyntaxError by providing all the positional arguments first, followed by the keyword arguments at last.

Ну, на самом деле, история аргументов в Python не такая уж и большая.

Я всегда удивлялся тому, что для работы с аргументами Python-функций достаточно лишь разобраться с *args и **kwargs. И удивлялся я не зря. Как оказалось, аргументы — это далеко не так просто. В этом материале я хочу дать общий обзор всего того, что связано с аргументами функций в Python. Надеюсь, что в итоге у меня, и правда, получится показать общую картину работы с аргументами, и что эта статья не станет очередной публикацией, в которой читателю не удастся найти ничего нового. А теперь — к делу.

Большинству читателей этой статьи, полагаю, понятна сущность аргументов функций. Для начинающих поясню, что это — объекты, отправляемые функции инициатором её вызова. При передаче аргументов функции выполняется множество действий, зависящих от того, объекты какого типа отправляют функции (изменяемые или неизменяемые объекты). Инициатор вызова функции — это сущность, которая вызывает функцию и передаёт ей аргументы. Говоря о вызове функций, стоит поразмыслить над некоторыми вещами, которые мы сейчас обсудим.

В аргументы, имена которых заданы при объявлении функции, записываются объекты, передаваемые функциям при вызове. При этом, если соответствующим локальным переменным функций, их параметрам, что-то присваивают, эта операция не влияет на передаваемые функциям неизменяемые объекты. Например:

def foo(a):
    a = a+5
    print(a)             # Выводит 15

a = 10
foo(a)
print(a)                 # Выводит 10

Как видно, вызов функции никак не повлиял на переменную a. Именно это происходит в том случае, если функции передаётся неизменяемый объект.

А если же функциям передают изменяемые объекты, то можно столкнуться с поведением системы, которое отличается от вышеописанного.

def foo(lst):
    lst = lst + ['new entry']
    print(lst)                # Выводит ['Book', 'Pen', 'new entry']

lst = ['Book', 'Pen']
print(lst)                    # Выводит ['Book', 'Pen']
foo(lst)
print(lst)                    # Выводит ['Book', 'Pen']

Заметили ли вы тут что-то новое? Если вы ответите «Нет», то будете правы. Но если как-то повлиять на элементы изменяемого объекта, переданного функции, мы станем свидетелями кое-чего другого.

def foo(lst):
    lst[1] = 'new entry'
    print(lst)                # Выводит ['Book', 'new entry']

lst = ['Book', 'Pen']
print(lst)                     # Выводит ['Book', 'Pen']
foo(lst)
print(lst)                     # Выводит ['Book', 'new entry']

Как видите, объект из параметра lst был изменён после вызова функции. Произошло это из-за того, что мы работаем со ссылкой на объект, хранящейся в параметре lst. В результате изменение содержимого этого объекта выходит за пределы функции. Избежать этого можно, просто выполняя глубокие копии подобных объектов и записывая их в локальные переменные функции.

def foo(lst):
    lst = lst[:]
    lst[1] = 'new entry'
    print(lst)                   # Выводит ['Book', 'new entry']

lst = ['Book', 'Pen']
print(lst)                       # Выводит ['Book', 'Pen']
foo(lst)
print(lst)                       # Выводит ['Book', 'Pen']

Это вас ещё не удивило? Если нет — тогда хотелось бы мне сделать так, чтобы вы, пропустив то, что вам известно, сразу же перешли к новому для вас материалу. А если да — то, помяните мои слова, вы, ближе знакомясь с аргументами, узнаете ещё много интересного.

Итак, вот что следует знать об аргументах функций:

  1. Порядок передачи функциям позиционных аргументов.
  2. Порядок передачи функциям именованных аргументов.
  3. Назначение значений аргументов, применяемых по умолчанию.
  4. Организация обработки наборов аргументов переменной длины.
  5. Распаковка аргументов.
  6. Использование аргументов, которые можно передавать только по имени (keyword-only).

Разберём каждый из этих пунктов.

1. Порядок передачи функциям позиционных аргументов

Позиционные аргументы обрабатываются слева направо. То есть оказывается, что позиция аргумента, переданного функции, находится в прямом соответствии с позицией параметра, использованного в заголовке функции при её объявлении.

def foo(d, e, f):
    print(d, e, f)

a, b, c = 1, 2, 3
foo(a, b, c)                  # Выводит 1, 2, 3
foo(b, a, c)                  # Выводит 2, 1, 3
foo(c, b, a)                  # Выводит 3, 2, 1

Переменные a, b и c имеют, соответственно, значения 1, 2 и 3. Эти переменные играют роль аргументов, с которыми вызывается функция foo. Они, при первом вызове функции, соответствуют параметрам d, e и f. Этот механизм применим практически во всех из вышеперечисленных выше 6 пунктов, касающихся того, что нужно знать об аргументах функций в Python. Место размещения позиционного аргумента, передаваемого функции при вызове, играет главную роль при назначении значений параметрам функции.

2. Порядок передачи функциям именованных аргументов

Именованные аргументы передают функциям с указанием имён этих аргументов, соответствующих тем именам, которые им назначены при объявлении функции.

def foo(arg1=0, arg2=0, arg3=0):
    print(arg1, arg2, arg3)

a, b, c = 1, 2, 3
foo(a,b,c)                          # Выводит 1 2 3
foo(arg1=a, arg2=b, arg3=c)         # Выводит 1 2 3
foo(arg3=c, arg2=b, arg1=a)         # Выводит 1 2 3
foo(arg2=b, arg1=a, arg3=c)         # Выводит 1 2 3

Как видите, функция foo принимает 3 аргумента. Эти аргументы имеют имена arg1, arg2 и arg3. Обратите внимание на то, как мы, при вызове функции, меняем позиции аргументов. Именованные аргументы обрабатываются не так, как позиционные, хотя система продолжает читать их слева направо. Python, при назначении соответствующих значений параметрам функций, учитывает имена аргументов, а не их позиции. В результате оказывается, что функция выводит одно и то же независимо от позиций переданных ей аргументов. Это — всегда 1 2 3.

Обратите внимание на то, что здесь продолжают действовать механизмы, описанные в пункте №1.

3. Назначение значений аргументов, применяемых по умолчанию

Именованным аргументам можно назначать значения, применяемые по умолчанию. При использовании этого механизма в функции определённые аргументы становятся необязательными. Объявление подобных функций выглядит как то, что мы рассматривали в пункте №2. Единственное различие заключается в том, как именно вызываются эти функции.

def foo(arg1=0, arg2=0, arg3=0):
    print(arg1, arg2, arg3)

a, b, c = 1, 2, 3
foo(arg1=a)                         # Выводит 1 0 0
foo(arg1=a, arg2=b )                # Выводит 1 2 0
foo(arg1=a, arg2=b, arg3=c)         # Выводит 1 2 3

Обратите внимание на то, что в этом примере мы не передаём функции все аргументы, описанные при её объявлении. В этих случаях соответствующим параметрам назначаются значения, заданные по умолчанию. Продолжим этот пример:

foo(arg2=b)                         # Выводит 0 2 0
foo(arg2=b, arg3=c )                # Выводит 0 2 3

foo(arg3=c)                         # Выводит 0 0 3
foo(arg3=c, arg1=a )                # Выводит 1 0 3

Это — простые и понятные примеры использования вышеописанных механизмов вызова функций с передачей ей именованных аргументов. А теперь давайте усложним наши эксперименты, объединив то, о чём мы до сих пор говорили в пунктах №1, №2 и №3:

foo(a, arg2=b)                      # Выводит 1 2 0
foo(a, arg2=b, arg3=c)              # Выводит 1 2 3
foo(a, b, arg3=c)                   # Выводит 1 2 3

foo(a)                              # Выводит 1 0 0
foo(a,b)                            # Выводит 1 2 0

Тут при вызове функции использованы и позиционные и именованные аргументы. При использовании позиционных аргументов порядок их указания играет, как и прежде, важнейшую роль в правильной передаче функции входных данных.

Здесь мне хотелось бы обратить ваше внимание на одну примечательную деталь. Она заключается в том, что позиционные аргументы нельзя указывать после именованных аргументов. Вот пример, который позволит вам лучше понять эту идею:

foo(arg1=a, b)
>>>
foo(arg1=a, b)
           ^
SyntaxError: positional argument follows keyword argument
foo(a, arg2=b, c)
>>>
foo(a, arg2=b, c)
              ^
SyntaxError: positional argument follows keyword argument

Вы можете воспринимать это как правило. Позиционные аргументы не должны следовать за именованными аргументами при вызове функции.

4. Организация обработки наборов аргументов переменной длины

Здесь речь пойдёт о конструкциях *args и **kwargs. Когда эти конструкции используются при объявлении функции, мы ожидаем, что при вызове функции наборы аргументов произвольной длины будут представлены в виде параметров args и kwargs. При применении конструкции *args в параметр args попадают позиционные аргументы, представляемые в виде кортежа. При применении **kwargs в kwargs попадают именованные аргументы, представленные в виде словаря.

def foo(*args):
    print(args)

a, b, c = 1, 2, 3

foo(a, b, c)                # Выводит (1, 2, 3)
foo(a, b)                   # Выводит (1, 2)
foo(a)                      # Выводит (1)
foo(b, c)                   # Выводит (2, 3)

Этот код доказывает то, что в параметре args хранится кортеж, содержащий то, что передано функции при её вызове.

def foo(**kwargs):
    print(kwargs)

foo(a=1, b=2, c=3)        # Выводит {'a': 1, 'b': 2, 'c': 3}
foo(a=1, b=2)             # Выводит {'a': 1, 'b': 2}
foo(a=1)                  # Выводит {'a': 1}
foo(b=2, c=3)             # Выводит {'b': 2, 'c': 3}

В вышеприведённом коде показано то, что в параметре kwargs хранится словарь, состоящий из пар ключ-значение и представляющий именованные аргументы, переданные функции при вызове.

Но надо отметить, что функции, рассчитанной на приём позиционных аргументов, нельзя передавать именованные аргументы (и наоборот).

def foo(*args):
    print(args)

foo(a=1, b=2, c=3)
>>>
foo(a=1, b=2, c=3)
TypeError: foo() got an unexpected keyword argument 'a'
#########################################################
def foo(**kwargs):
    print(kwargs)

a, b, c = 1, 2, 3
foo(a, b, c)
>>>
TypeError: foo() takes 0 positional arguments but 3 were given

А теперь давайте соберём вместе всё то, что мы разобрали в пунктах №1, №2, №3 и №4, и со всем этим поэкспериментируем, исследовав разные комбинации аргументов, которые можно передавать функциям при их вызове.

def foo(*args,**kwargs):
    print(args, kwargs)

foo(a=1,)
# () {'a': 1}

foo(a=1, b=2, c=3)
# () {'a': 1, 'b': 2, 'c': 3}

foo(1, 2, a=1, b=2)
# (1, 2) {'a': 1, 'b': 2}

foo(1, 2)
# (1, 2) {}

Как видите, в нашем распоряжении оказывается кортеж args и словарь kwargs.

А вот — ещё одно правило. Оно заключается в том, что конструкцию *args нельзя использовать после конструкции **kwargs.

def foo(**kwargs, *args):
    print(kwargs, args)
>>>
    def foo(**kwargs, *args):
                      ^
SyntaxError: invalid syntax

То же самое правило распространяется и на порядок указания аргументов при вызове функций. Позиционные аргументы не должны следовать за именованными.

foo(a=1, 1)
>>>
    foo(a=1, 1)
            ^
SyntaxError: positional argument follows keyword argument
foo(1, a=1, 2)
>>>
    foo(1, a=1, 2)
               ^
SyntaxError: positional argument follows keyword argument

При объявлении функций можно комбинировать позиционные аргументы, *args и *kwagrs следующим образом:

def foo(var, *args,**kwargs):
    print(var, args, kwargs)

foo(1, a=1,)                            # Вызов 1
# 1 () {'a': 1}

foo(1, a=1, b=2, c=3)                   # Вызов 2
# 1 () {'a': 1, 'b': 2, 'c': 3}

foo(1, 2, a=1, b=2)                     # Вызов 3
# 1 (2,) {'a': 1, 'b': 2}
foo(1, 2, 3, a=1, b=2)                  # Вызов 4
# 1 (2, 3) {'a': 1, 'b': 2}
foo(1, 2)                               # Вызов 5
# 1 (2,) {}

При объявлении функции foo мы исходили из того, что у неё должен быть один обязательный позиционный аргумент. За ним следует набор позиционных аргументов переменной длины, а за этим набором идёт набор именованных аргументов переменной длины. Зная это, мы легко сможем «расшифровать» каждый из вышеприведённых вызовов функции.

В Вызове 1 функции переданы аргументы 1 и a=1. Это, соответственно, позиционный и именованный аргументы. Вызов 2 — это разновидность Вызова 1. Здесь длина набора позиционных аргументов равна нулю.

В Вызове 3 мы передаём функции 1, 2 и a=1,b=2. Это значит, что она теперь принимает два позиционных аргумента и два именованных аргумента. В соответствии с объявлением функции оказывается, что 1 воспринимается как обязательный позиционный аргумент, 2 идёт в набор позиционных аргументов переменной длины, а a=1 и b=2 попадают в набор именованных аргументов переменной длины.

Для того чтобы правильно вызвать эту функцию, мы должны передать ей, как минимум, один позиционный аргумент. В противном случае мы столкнёмся с ошибкой.

def foo(var, *args,**kwargs):
    print(var, args, kwargs)

foo(a=1)
>>>
foo(a=1)
TypeError: foo() missing 1 required positional argument: 'var'

Ещё одной разновидностью подобной функции может стать функция, в объявлении которой указано, что она принимает один обязательный позиционный аргумент и один именованный аргумент, за которыми следуют наборы позиционных и именованных аргументов переменной длины.

def foo(var, kvar=0, *args,**kwargs):
    print(var, kvar, args, kwargs)

foo(1, a=1,)                               # Вызов 1
# 1 0 () {'a': 1}

foo(1, 2, a=1, b=2, c=3)                   # Вызов 2
# 1 0 () {'a': 1, 'b': 2, 'c': 3}

foo(1, 2, 3, a=1, b=2)                     # Вызов 3
# 1 2 () {'a': 1, 'b': 2}

foo(1, 2, 3, 4, a=1, b=2)                  # Вызов 4
# 1 2 (3,) {'a': 1, 'b': 2}

foo(1, kvar=2)                             # Вызов 5
# 1 2 () {}

Вызовы этой функции можно «расшифровать» так же, как это делалось при анализе предыдущей функции.

При вызове этой функции ей надо передавать, как минимум, один позиционный аргумент. Иначе мы столкнёмся с ошибкой:

foo()
>>>
foo()
TypeError: foo() missing 1 required positional argument: 'var'
foo(1)
# 1 0 () {}

Обратите внимание на то, что вызов foo(1) работает нормально. Дело тут в том, что в том случае, если функцию вызывают, не указывая значение для именованного аргумента, значение ему назначается автоматически.

А вот ещё некоторые ошибки, с которыми можно столкнуться при неправильном вызове этой функции:

foo(kvar=1)                             # Вызов 1
>>>
TypeError: foo() missing 1 required positional argument: 'var'
foo(kvar=1, 1, a=1)                      # Вызов 2
>>>
SyntaxError: positional argument follows keyword argument
foo(1, kvar=2, 3, a=2)                   # Вызов 3
>>>
SyntaxError: positional argument follows keyword argument

Обратите особое внимание на ошибку, возникающую при выполнении Вызова 3.

5. Распаковка аргументов

В предыдущих разделах мы говорили о том, как собирать в кортежи и словари наборы аргументов, передаваемых функциям. А здесь мы обсудим обратную операцию. А именно, разберём механизм, позволяющий распаковывать аргументы, подаваемые на вход функции.

args = (1, 2, 3, 4)
print(*args)                  # Выводит 1 2 3 4
print(args)                   # Выводит (1, 2, 3, 4)

kwargs = { 'a':1, 'b':2}
print(kwargs)                 # Выводит {'a': 1, 'b': 2}
print(*kwargs)                # Выводит a b

Распаковывать переменные можно с помощью синтаксических конструкций * и **. Вот как выглядит их использование при передаче в функции кортежей, списков и словарей.

def foo(a, b=0, *args, **kwargs):
    print(a, b, args, kwargs)

tup = (1, 2, 3, 4)
lst = [1, 2, 3, 4]
d = {'e':1, 'f':2, 'g':'3'}

foo(*tup)             # foo(1, 2, 3, 4)
# 1 2 (3, 4) {}

foo(*lst)             # foo(1, 2, 3, 4)
# 1 2 (3, 4) {}

foo(1, *tup)          # foo(1, 1, 2, 3, 4)
# 1 1 (2, 3, 4) {}

foo(1, 5, *tup)       # foo(1, 5, 1, 2, 3, 4)
# 1 5 (1, 2, 3, 4) {}

foo(1, *tup, **d)     # foo(1, 1, 2, 3, 4 ,e=1 ,f=2, g=3)
# 1 1 (2, 3, 4) {'e': 1, 'f': 2, 'g': '3'}

foo(*tup, **d)         # foo(1, 1, 2, 3, 4 ,e=1 ,f=2, g=3)
# 1 2 (3, 4) {'e': 1, 'f': 2, 'g': '3'}
d['b'] = 45
foo(2, **d)             # foo(1, e=1 ,f=2, g=3, b=45)
# 2 45 () {'e': 1, 'f': 2, 'g': '3'}

Разберите каждый из приведённых здесь вызовов функций, выполненный с использованием распаковки аргументов, и обратите внимание на то, как соответствующие вызовы выглядели бы без использования * и **. Постарайтесь понять то, что происходит при выполнении этих вызовов, и то, как именно распаковываются различные структуры данных.

Экспериментируя с распаковкой аргументов, можно столкнуться с новой ошибкой:

foo(1, *tup, b=5)
>>>
TypeError: foo() got multiple values for argument 'b'
foo(1, b=5, *tup)
>>>
TypeError: foo() got multiple values for argument 'b'

Эта ошибка возникает из-за конфликта именованного аргумента, b=5, и позиционного аргумента. Как мы выяснили в разделе №2, при передаче именованных аргументов их порядок значения не имеет. В результате в обоих случаях возникает одна и та же ошибка.

6. Использование аргументов, которые можно передавать только по имени (keyword-only)

В некоторых случаях нужно сделать так, чтобы функция принимала бы обязательные именованные аргументы. Если при объявлении функции описывают аргументы, которые можно передавать только по имени, то такие аргументы должны передаваться ей при любом её вызове.

def foo(a, *args, b):
    print(a, args, b)

tup = (1, 2, 3, 4)

foo(*tup, b=35)
# 1 (2, 3, 4) 35

foo(1, *tup, b=35)
# 1 (1, 2, 3, 4) 35

foo(1, 5, *tup, b=35)
# 1 (5, 1, 2, 3, 4) 35

foo(1, *tup, b=35)
# 1 (1, 2, 3, 4) 35

foo(1, b=35)
# 1 () 35

foo(1, 2, b=35)
# 1 (2,) 35

foo(1)
# TypeError: foo() missing 1 required keyword-only argument: 'b'

foo(1, 2, 3)
# TypeError: foo() missing 1 required keyword-only argument: 'b'

Как видите, ожидается, что функции обязательно будет передан именованный аргумент b, который, в объявлении функции, указан после *args. При этом в объявлении функции можно использовать просто символ *, после которого, через запятую, идут идентификаторы именованных аргументов, которые можно передавать функции только по имени. Такая функция не будет рассчитана на приём набора позиционных аргументов переменной длины.

def foo(a, *, b, c):
    print(a, b, c)

tup = (1, 2, 3, 4)

foo(1, b=35, c=55)
# 1 35 55

foo(c= 55, b=35, a=1)
# 1 35 55

foo(1, 2, 3)
# TypeError: foo() takes 1 positional argument but 3 were given

foo(*tup, b=35)
# TypeError: foo() takes 1 positional argument but 4 positional arguments (and 1 keyword-only argument) were given

foo(1, b=35)
# TypeError: foo() takes 1 positional argument but 4 positional arguments (and 1 keyword-only argument) were given

Функция, объявленная в предыдущем примере, принимает один позиционный аргумент и два именованных аргумента, которые можно передавать только по имени. Это приводит к тому, что для правильного вызова функции ей необходимо передавать оба именованных аргумента. После * можно описывать и именованные аргументы, которым заданы значения, применяемые по умолчанию. Это даёт нам определённую свободу при вызове подобных функций.

def foo(a, *, b=0, c, d=0):
    print(a, b, c, d)

foo(1, c=55)
# 1 0 55 0

foo(1, c=55, b=35)
# 1 35 55 0

foo(1)
# TypeError: foo() missing 1 required keyword-only argument: 'c'

Обратите внимание на то, что функцию можно нормально вызывать, не передавая ей аргументы b и d, так как для них заданы значения, применяемые по умолчанию.

Итоги

Пожалуй, у нас, и правда, получилась очень длинная история об аргументах. Надеюсь, читатели этого материала узнали что-то новое для себя. И, кстати, историю об аргументах функций в Python можно продолжать. Возможно, мы ещё о них поговорим.

Узнали ли вы из этого материала что-то новое об аргументах функций в Python?

Image of How to Fix: Positional Argument Follows Keyword Argument in Python

Table of Contents

  • Introduction
  • Positional and Keyword Arguments in Python
  • What is SyntaxError: positional argument follows keyword argument?
  • How to Fix SyntaxError: positional argument follows keyword argument?
  • Using Only Positional Arguments
  • *args and **kwargs Parameters in Python
  • Summary
  • Next Steps
  • References

Introduction

Arguments (or parameters) are a fundamental concept in Python programming. They allow you to provide inputs to your programs and functions that result in a varying output return value or varying set of steps performed by your program.

In Python, you might have encountered the error SyntaxError: Positional Argument Follows Keyword Argument when working with positional and keywords arguments together in one function. To resolve this error you must understand how arguments fundamentally work in Python.

In this article, you will learn how to fix the «SyntaxError: Positional Argument Follows Keyword Argument» in Python by understanding what positional and keyword arguments are and how they work, which will help you prevent this error from occurring in the future.

Positional and Keyword Arguments in Python

Arguments allow developers and users to provide input values to a program or function that returns a varying output based on the arguments supplied. In Python, arguments are most commonly used when calling functions and class methods — a class method is just a function defined as a part of a class. If you are familiar with the Linux command line, you likely have already used arguments with some Linux commands.

The terms «parameter» and «argument» are often used interchangeably. As a refresher, let’s quickly mention the difference these two terms:

  • A parameter is a scoped variable defined in the function header.
  • An argument is the value passed as input via a function call, which is mapped to a parameter.

Python has two important types of arguments, positional arguments and keyword arguments.

You are probably most familiar with positional arguments, since they are the default type in Python.

Positional arguments are simply an ordered list of inputs in a Python function call that correspond to the order of the parameters defined in the function header.

>>> def func(num1, num2):
...     print(f"Num 1: {num1}, Num 2: {num2}")
... 
>>> func(1, 2)
Num 1: 1, Num 2: 2
>>>
>>> func(2, 1)
Num 1: 2, Num 2: 1

In this example, we have defined a the function func with parameters num1, and num2. When calling the function, the argument order matters. Python uses the position of the arguments to determine the parameter to map each input value to.

On the other hand, a keyword argument is supplied with both a parameter name AND its corresponding value.

>>> def func(num1, num2):
...     print(f"Num 1: {num1}, Num 2: {num2}")
...
>>> func(num1=1, num2=2)
Num 1: 1, Num 2: 2
>>>
>>> func(num2=2, num1=1)
Num 1: 1, Num 2: 2

Here, you can see how keyword arguments are used, and how changing the order of the arguments doesn’t matter because you specify exactly which parameter refers to which value.

What is SyntaxError: positional argument follows keyword argument?

The Python SyntaxError: positional argument follows keyword argument occurs when you try to specify a positional argument after a keyword argument in a function call.

>>> def func(num1, num2):
...     print(f"Num 1: {num1}, Num 2: {num2}")
... 
>>> func(num1=1, 2)
  File "<stdin>", line 1
    func(num1=1, 2)
                  ^
SyntaxError: positional argument follows keyword argument

Here, the SyntaxError occurred because the keyword argument num1=1 is followed by the positional argument 2.

The logic behind why the SyntaxError occurs is that in order for Python to consistently map all supplied argument values to named parameters, all positional arguments must be specified before any keyword arguments.

How to Fix SyntaxError: positional argument follows keyword argument?

There are multiple ways to fix the Python exception SyntaxError: positional argument follows keyword and each method has its pros and cons.

Using Positional Arguments Followed by Keyword Arguments

One method is to simply do what the error states and specify all positional arguments before our keyword arguments!

>>> func(1, num2=2)
Num 1: 1, Num 2: 2

Here, we use the positional argument 1 followed by the keyword argument num2=2 which fixes the error. However, you might have noticed that in the previous example we used a keyword argument for the num1 parameter instead of the num2 parameter. If you want to use both positional and keyword arguments, all the positional arguments must come before the keyword arguments.

In Python, optional arguments can be implemented by specifying a default value for a parameter in the function header. This can be done using syntax like «def func(num1, num2=10):». This makes the num2 parameter totally optional. If it’s not specified in the function call, num2 will assume the default value of 10.

This method of using arguments is great when working with functions that have some required arguments, which you can use as positional arguments, and any additional optional arguments can be keyword arguments. This makes it clear which of the arguments passed were optional and which were required. Many times there can be a large number of optional arguments, and it would be impractical to refer to them without using keyword arguments.

Using Only Positional Arguments

Another way to resolve this error is to exclusively use positional arguments in your function call:

>>> func(1, 2)
Num 1: 1, Num 2: 2

This can be great when you have a few arguments and you want to keep things simple. However, this could make the code harder to understand as other developers don’t know what each argument means right away. They would have to look at the function definition or the function documentation. And it’s even worse as the number of arguments increases. It is also impossible to use this method with optional arguments, without passing the default values again in the function call. This is a bit redundant and prone to errors when specifying default values repeatedly in the function calls.

Using Only Keyword Arguments

Finally, you can fix the error by using only keyword arguments:

>>> func(num1=1, num2=2)
Num 1: 1, Num 2: 2
>>>
>>> func(num2=2, num1=1)
Num 1: 1, Num 2: 2

Using this method, you can explicitly state which parameter equals which value, and the order of the arguments doesn’t matter since Python knows which parameter name to map each value to. It also makes the code easier for other developers to understand since there is less ambiguity.

This method also easily works with optional arguments. The only downside of this method is that it can be pretty verbose, and you would need to know the name of every parameter when writing a function call.

*args and **kwargs Parameters in Python

Two more ways to define and pass arguments in Python are *args and **kwargs. Using the single asterisk * or double asterisk ** syntax before a parameter name in a function header allows you to pass a varying number of non-keyword or keyword arguments in a function call. Note that *args stands for «arguments» and **kwargs stands for «keyword arguments».

*args accepts any number of positional arguments which are ingested as a tuple object, with each argument value being included as an element in the tuple. **kwargs accepts any number of keyword arguments which are ingested as a dictionary object. Each keyword argument name is included as a key in the dictionary, and each corresponding keyword argument value is included as a value in the dictionary.

For example:

>>> def f_args(*args):
...     print(args)
... 
>>> f_args(1, 2, 3)
(1, 2, 3)
>>> 
>>> def f_kwargs(**kwargs):
...     print(kwargs)
... 
>>> f_kwargs(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}

Here, we have two functions f_args and f_kwargs, which define *args and **kwargs parameters, respectively. You can see that *args stores a tuple of positional arguments in the variable args, and **kwargs stores a dictionary of keyword arguments in the variable kwargs.

Note that the variable names args and kwargs can be replaced with any other variable name, only the single * or double ** asterisk syntax is important to define how the arguments are ingested.

Here is another example usage of *args:

>>> def my_sum(*nums):
...     total = 0
...     for num in nums:
...             total += num
...     return total
... 
>>> my_sum(1, 2, 3)
6
>>>
>>> my_sum(2, 2, 2, 5)
11
>>>
>>> my_sum()
0

The my_sum function accepts any amount of positional arguments (or no arguments at all), and returns the sum of those arguments.

You can also use both *args and **kwargs together:

>>> def f(*args, **kwargs):
...     print(args, kwargs)
... 
>>> f(1, 2, a=3)
(1, 2) {'a': 3}

Here, all the positional arguments are included in the tuple args, and all the keyword arguments are included in the dictionary kwargs. Note that all positional * parameters must come before keyword ** parameters, or you’ll get an invalid syntax error as below:

>>> def f(**kwargs, *args):
  File "<stdin>", line 1
    def f(**kwargs, *args):
                    ^
SyntaxError: invalid syntax
>>> 

Summary

In this article, you learned how to fix the Python error `SyntaxError: Positional Argument Follows Keyword Argument» using various methods and learned about the different types of arguments in Python.

First, you learned what arguments are and some terminology regarding arguments. Then you learned what positional arguments are and what keyword arguments are.

Next, you saw when the «SyntaxError: Positional Argument Follows Keyword Argument» occurs with an example, and why it occurs. Which was followed, with various methods to fix the error and the benefits and drawbacks of each method.

Additionally, you learned what the *args and **kwargs arguments are in Python and how to use them.

Next Steps

To learn more about the basics of Python, coding, and software development, check out our Coding Essentials Guidebook for Developers, where we cover the essential languages, concepts, and tools that you’ll need to become a professional developer.

Thanks and happy coding! We hope you enjoyed this article. If you have any questions or comments, feel free to reach out to jacob@initialcommit.io.

References

  1. Python args and kwargs: Demystifie — https://realpython.com/python-kwargs-and-args/
  2. Python Function Arguments — https://www.programiz.com/python-programming/function-argument

Final Notes

There are two types of arguments in Python: keyword and positional arguments. The syntax of Python requires that these types of arguments appear in a particular order. If you place a positional argument after a keyword argument, the Python interpreter will throw the error “SyntaxError: positional argument follows keyword argument”.

To solve this problem, ensure that you specify the key for all arguments or ensure the keyword arguments come after the positional arguments.

This tutorial will go through the error in detail and an example to learn how to solve it.


Table of contents

  • SyntaxError: positional argument follows keyword argument
    • What is a SyntaxError in Python?
    • Keyword and Positional Arguments in Python
  • Example
    • Solution
  • Summary

SyntaxError: positional argument follows keyword argument

What is a SyntaxError in Python?

The term syntax refers to the rules that define the various combinations of symbols to instruct a computer to perform tasks. A syntax error violates the syntax rules for a given programming language, and a syntax error is similar to a grammatical error in human languages.

When you run a Python program, the interpreter will parse it to convert the code into Python byte code to execute it. If there is invalid syntax in the Python code during the parsing stage of execution, the interpreter will throw a SyntaxError.

For further reading on SyntaxError involving arguments, go to the article: How to Solve Python SyntaxError: non-default argument follows default argument.

Keyword and Positional Arguments in Python

There are two types of arguments for functions in Python, keyword and positional. We identify a keyword argument by a key, whereas we identify a positional argument by its position in the function definition. Let’s look at an example.

def test_func(x, y, z = 5):
    
    print('x = ', x)
    
    print('y = ', y)
    
    print('z = ', z)

print('Example Function call 1')

test_func(2, 4, 6)

print('Example Function call 2')

test_func(2, 4)

print('Example Function call 3')

test_func(z=10, x=3, y=2)

In the above program, we have a function called test_func that takes three arguments. We then perform three function calls with different positional and keyword arguments.

Let’s run all three function calls to get the result:

Example Function call 1
x =  2
y =  4
z =  6
Example Function call 2
x =  2
y =  4
z =  5
Example Function call 3
x =  3
y =  2
z =  10
  • In the first function call, we provide three positional arguments. In this case, the order of the arguments must match the order the function expects them.
  • In the second function call we provide only two positional arguments. The code still works because the final argument z is a keyword argument with a default value of 5. Therefore, if we do not specify a different keyword argument the function uses the default value.
  • In third function call, we provide three keyword arguments. In this case the order of the arguments is different from what the function has as default. If you are passing all keyword arguments you do not need to be specific in the positions of the arguments.

Example

Let’s consider an example program that will throw the SyntaxError. We will write a program that creates a dictionary of player names and scores for a game.

players = ["Jane", "Wilson", "Rupert"]

scores = [4, 8, 7]

def scoring_func(players, scores):

    score_dict = dict(zip(players, scores))

    print(score_dict)

In the code, we define two lists, one for player names and one for the scores of each player. The function scoring_func() takes the two lists as positional arguments and uses dict() and zip() to convert the two lists into a dictionary. The function then prints the result to the console. Let’s call the function:

scoring_func(players=players, scores)
    scoring_func(players=players, scores)
                                  ^
SyntaxError: positional argument follows keyword argument

The code throws the SyntaxError because the positional argument scores came after the keyword argument players.

Solution

We can solve this problem in three ways. Firstly we can make all of the arguments positional. Let’s look at the revised code:

players = ["Jane", "Wilson", "Rupert"]

scores = [4, 8, 7]

def scoring_func(players, scores):

    score_dict = dict(zip(players, scores))

    print(score_dict)

scoring_func(players, scores)

When we perform the function call, we pass two positional arguments. Let’s run the code to see what happens:

{'Jane': 4, 'Wilson': 8, 'Rupert': 7}

For the second option, if we want to use a keyword, we must ensure no positional arguments follow a keyword argument. Therefore scores can be a keyword argument. Let’s look at the revised code:

players = ["Jane", "Wilson", "Rupert"]

scores = [4, 8, 7]

def scoring_func(players, scores):

    score_dict = dict(zip(players, scores))

    print(score_dict)

scoring_func(players, scores=scores)

When we perform the function call, we pass one positional argument, players and one keyword argument, scores. Let’s run the code to see what happens:

{'Jane': 4, 'Wilson': 8, 'Rupert': 7}

Lastly, for the third option, we can use all keyword arguments. In this case, we can use any order for our arguments. Let’s look at the revised code:

players = ["Jane", "Wilson", "Rupert"]

scores = [4, 8, 7]

def scoring_func(players, scores):

    score_dict = dict(zip(players, scores))

    print(score_dict)

scoring_func(players=players, scores=scores)

We pass two keyword arguments to the function when we perform the function call. Let’s run the code to get the result:

{'Jane': 4, 'Wilson': 8, 'Rupert': 7}

To summarise the options, go through the following table

Arguments Allowed?
All position arguments, e.g. foo(1, 2, 3) Yes
Positional argument(s) followed by keyword argument(s) e.g.
foo(3, y=2, z=4)
foo(3, 2, z=4)
Yes
All keyword arguments e.g.
foo(x=3, y=2, z=4)
Yes
Keyword argument(s) followed by positional argument(s) e.g.
foo(x=3, y=2, 4)
foo(x=3, 2, z=4)
foo(3, y=2, z)
No
Argument configurations allowed/not allowed in Python.

Summary

Congratulations on reading to the end of this tutorial! Positional arguments must appear before keyword arguments. If you do not follow this syntax, you will throw the error “SyntaxError: positional argument follows keyword argument”. If you use all keywords, you can avoid this error and pass the arguments in any order. When passing arguments to functions, keywords may also make your code more readable.

Go to the online courses page on Python to learn more about Python for data science and machine learning.

Have fun and happy researching!

Update: This post was originally published on my blog decodingweb.dev as part of the Python Syntax Errors series. You can read the latest version on my blog for a 💯 user experience.

Python raises the “SyntaxError: positional argument follows keyword argument” error if you place one or more keyword arguments (e.g., age=35, name=John) before your positional arguments (e.g., 35, John) in a function call.

Based on Python syntax, keyword arguments must follow positional arguments and not the other way around:

def greet(name, message):
  return f'Hi {name}, {message}!'

# 🚫 SyntaxError
print(greet(name='John', 'Welcome'))

Enter fullscreen mode

Exit fullscreen mode

Here’s what the error looks like:

File /dwd/sandbox/test.py, line 5
  print(greet(name='John', 'Welcome!'))
                                      ^
SyntaxError: positional argument follows keyword argument

Enter fullscreen mode

Exit fullscreen mode

In the above example, the keyword argument name='John' shouldn’t appear before the positional argument 'Welcome' when calling the greet() function.

How to fix SyntaxError: positional argument follows keyword argument

To fix this syntax error, you have three options:

1. Pass keyword arguments after positional arguments
2. Pass all the arguments as positional arguments
3. Pass all the arguments as keyword arguments

Let’s explore each approach with some examples.

1. Pass keyword arguments after positional arguments: Based on Python syntax, keyword arguments must follow positional arguments:

def greet(name, message):
  return f'Hi {name}, {message}!'

# ✅ Correrct
print(greet('John', message='Welcome'))

# 🚫 Wrong
print(greet(name='John', 'Welcome'))

Enter fullscreen mode

Exit fullscreen mode

Even if only one keyword argument appears before a positional argument, you’ll get the «SyntaxError: positional argument follows keyword argument» error.

2. Pass all the arguments as positional arguments: In this approach, we need to make sure we pass the values in the order they appear in the function’s definition:

def greet(name, message):
  return f'Hi {name}, {message}!'

# ✅ Correct
print(greet('John', 'Welcome'))
# expected output: Hi John, Welcome!

# 🚫 Wrong
print(greet('Welcome', 'John'))
# unexpected output: Hi Welcome!, John

Enter fullscreen mode

Exit fullscreen mode

3. Pass all the arguments as keyword arguments: Unlike positional arguments, the order doesn’t matter when passing keyword arguments. However, names must be correct:

def greet(name, message):
  return f'Hi {name}, {message}!'

# ✅ Correct
print(greet(message='Welcome!', name='John'))

Enter fullscreen mode

Exit fullscreen mode

A quick refresher on positional and keyword arguments
When calling a function, we can either pass the arguments as positional or keyword arguments — or a combination of both.

Here are a few examples:

# 2 positional arguments
greet('John', 'Welcome!')

# 2 keyword arguments
greet(message='Welcome!', name='John')

# 1 positional argument, 1 keyword argument
greet('John', message='Welcome!')

Enter fullscreen mode

Exit fullscreen mode

If we pass arguments as positional arguments, we need to be aware of their order because Python will map the values to variables in the order they appear in the function’s definition.

def greet(name, message):
   return f'Hi {name}, {message}!'

# ✅ Correct
print(greet('John', 'welcome!'))

Enter fullscreen mode

Exit fullscreen mode

The order doesn’t matter with keyword arguments, though.

However, you need to provide the parameter name as it appears in the function’s definition.

If you want to use keyword arguments, remember to place them after the positional ones. Otherwise, Python’s interpreter raises the «SyntaxError: positional argument follows keyword argument» error.

You can also have your function accept positional-only arguments. You can do that by placing a / after your parameters:

# ✅ Correct
def greet(name, message, /):
   return f'Hi {name}, {message}!'

Enter fullscreen mode

Exit fullscreen mode

As a result, if you invoke the function with a keyword argument, Python raises a TypeError.

This is good practice when making APIs; Using positional-only arguments in APIs helps you avoid breaking changes if a parameter name is modified in the future.

Alternatively, you can make your arguments keyword-only by placing a * before them.

# ✅ Correct
def greet(name, *, message):
   return f'Hi {name}, {message}!'

Enter fullscreen mode

Exit fullscreen mode

You can also combine the two to make some arguments positional-only, some keyword-only, and some both of them (the standard form):

# ✅ Correct
def greet(name, /, age *, message):
   return f'Hi {name}, {message}!'

Enter fullscreen mode

Exit fullscreen mode

In the above example, the name parameter must be passed as a positional argument (must be the first argument passed), and age is a standard parameter, meaning it can be a positional or keyword argument. And message must be a keyword argument since it’s preceded by a *.

Here’s the blueprint from Python.org

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only

Enter fullscreen mode

Exit fullscreen mode

How do I know when to use positional arguments, and when to use keyword arguments? You may ask.

Here’s the rule of thumb:

You can use positional arguments when the order of the parameters matters when calling the function.

Keyword-only arguments are helpful when the argument names are meaningful, and the function’s behavior is easier to understand with explicit names, or when you want to avoid people depending on the order of the arguments.

And that’s how you’d handle the «SyntaxError: positional argument follows keyword argument» error in Python.

Alright, I think it does it. I hope this quick guide helped you solve your problem.

Thanks for reading.


One error you may encounter in Python is:

SyntaxError: positional argument follows keyword argument

This error occurs when you use a positional argument in a function after using a keyword argument.

Here’s the difference between the two:

Positional arguments are ones that have no “keyword” in front of them.

  • Example: my_function(2, 2)

Keyword arguments are ones that do have a “keyword” in front of them.

  • Example: my_function(a=2, b=2)

If you use a positional argument after a keyword argument then Python will throw an error.

  • Example: my_function(a=2, 2)

The following example shows how this error may occur in practice.

Example: Positional Argument Follows Keyword Argument

Suppose we have the following function in Python that multiplies two values and then divides by a third:

def do_stuff(a, b):
    return a * b / c

The following examples show valid and invalid ways to use this function:

Valid Way #1: All Positional Arguments

The following code shows how to use our function with all positional arguments:

do_stuff(4, 10, 5)

8.0

No error is thrown because Python knows exactly which values to use for each argument in the function.

Valid Way #2: All Keyword Arguments

The following code shows how to use our function with all keyword arguments:

do_stuff(a=4, b=10, c=5)

8.0

Once again no error is thrown because Python knows exactly which values to use for each argument in the function.

Valid Way #3: Positional Arguments Before Keyword Arguments

The following code shows how to use our function with positional arguments used before keyword arguments:

do_stuff(4, b=10, c=5)

8.0

No error is thrown because Python knows that the value 4 must be assigned to the a argument.

Invalid Way: Positional Arguments After Keyword Arguments

The following code shows how we may attempt to use the function with positional arguments used after keyword arguments:

do_stuff(a=4, 10, 5)

SyntaxError: positional argument follows keyword argument

An error is thrown because we used positional arguments after keyword arguments.

Specifically, Python doesn’t know if the 10 and 5 values should be assigned to arguments b or c so it’s unable to execute the function.

Additional Resources

The following tutorials explain how to fix other common errors in Python:

How to Fix KeyError in Pandas
How to Fix: ValueError: cannot convert float NaN to integer
How to Fix: ValueError: operands could not be broadcast together with shapes

In Python, there are two types of arguments: positional and keyword arguments. These arguments must appear in a particular order otherwise the Python interpreter returns an error.

In this guide, we’re going to talk about the “positional argument follows keyword argument” error and why it is raised. We’ll look at an example code snippet with this error so that we can walk through how to solve it.

Get offers and scholarships from top coding schools illustration

Find Your Bootcamp Match

  • Career Karma matches you with top tech bootcamps
  • Access exclusive scholarships and prep courses

Select your interest

First name

Last name

Email

Phone number

By continuing you agree to our Terms of Service and Privacy Policy, and you consent to receive offers and opportunities from Career Karma by telephone, text message, and email.

Let’s get started!

The Problem: positional argument follows keyword argument

Let’s take a look at our full error:

SyntaxError: positional argument follows keyword argument

Like the English language, programming languages have their own rules. These rules are referred to as syntax. Our error is a syntax error which means that we have failed to follow one of the rules that governs how to write a Python code.

The next part of our error tells us what is causing this error. In this case, our code must have a positional argument that appears after a keyword argument.

Positional arguments are arguments that appear in their respective positions:

def add_numbers(a, b):
	return a + b

Let's call this function:

add_numbers(2, 3)

“a” and “b” become variables inside our function. This code works because we have specified two positional arguments. “a” is equal to 2 and “b” is equal to three. We can also specify these arguments as keyword arguments:

However, we cannot specify a positional argument first and then switch to the keyword syntax.

This is because Python has a special function called *args which processes multiple arguments in a function. Consider this code:

def show_users(a, b, *args):
	print(a, b, *args)

This code uses *args. This keyword represents a variable number of arguments. We can pass in as many arguments to our show_users() function as we want:

show_users("Alex", "Peter", "Violet', "Julie")

Our code returns: Alex Peter Violet Julie

Our first two arguments, “a” and “b”, have the values “Alex” and “Peter”, respectively.

This is because if you use positional syntax, arguments are assigned in the order in which they are passed. The last arguments appear in the order that they are stated because *args represents an unknown amount of additional arguments.

An Example Scenario

Let’s take a look at a code snippet that experiences this error:

def print_menu(salads, pizzas):
	print("Salad Menu")
	for s in salads:
		print(s)
	print("")
	print("Pizza Menu")
	for p in pizzas:
		print(p)

This function accepts two arguments: salads and pizzas. Our function prints out each salad on the salad menu and each pizza on the pizza menu to the console.

Let’s call our function:

salads = ["Tuna Salad", "Lettuce and Mango Salad", "Greek Salad"]
pizzas = ["Veggie Supreme", "Ham and Pineapple", "BBQ Chicken"]

print_menu(pizzas=pizzas, salads)

Our code returns:

File "main.py", line 13
	print_menu(pizzas=pizzas, salads)
                          	^
SyntaxError: positional argument follows keyword argument

There’s an error in our code, as we expected. Let’s fix it.

The Solution

To solve this problem, we need to make sure that all positional arguments come before keyword arguments. Let’s change how we call our function to reflect this rule:

print_menu(salads, pizzas)

We have specified two positional arguments: salads and pizzas. Alternatively, we could specify “pizzas” as as keyword argument after “salads”:

print_menu(salads, pizzas = pizzas)

In this example, it is unnecessary to add in any keyword arguments because we are not using the *args method. With that said, adding in keyword arguments can make code more readable depending on the number of values being passed into a function.

Let’s run our code with this revised function call:

Salad Menu
Tuna Salad
Lettuce and Mango Salad
Greek Salad

Pizza Menu
Veggie Supreme
Ham and Pineapple
BBQ Chicken

Our code successfully prints out our two Python lists.

Conclusion

Positional arguments must appear before a keyword argument in Python. This is because Python interprets positional arguments in the order in which they appear. Then, it interprets the keyword arguments that have been specified.

Now you’re ready to solve the “positional argument follows keyword argument” error like an expert Python developer!

Понравилась статья? Поделить с друзьями:
  • Port is error disabled cisco 2960
  • Position error exceeds the limit
  • Port in error or sync connect in error
  • Pos error handling облако
  • Port error mikrotik vpn