Недопустимый синтаксис в Python: распространенные причины ошибки синтаксиса
Оглавление
- Недопустимый синтаксис в Python
- Исключение синтаксической ошибки и обратная трассировка
- Распространенные синтаксические проблемы
- Заключение
Python известен своим простым синтаксисом. Однако, когда вы впервые изучаете Python или когда вы пришли к Python, имея солидный опыт работы с другим языком программирования, вы можете столкнуться с некоторыми вещами, которые Python не допускает. Если вы когда-либо получали сообщение SyntaxError
при попытке запустить свой код на Python, то это руководство может вам помочь. В этом руководстве вы увидите распространенные примеры недопустимого синтаксиса в Python и узнаете, как устранить проблему.
К концу этого урока вы сможете:
- Определить недопустимый синтаксис в Python
- Придайте смысл
SyntaxError
обратные следы - Устраните недопустимый синтаксис или полностью предотвратите его
Недопустимый синтаксис в Python
Когда вы запускаете свой код на Python, интерпретатор сначала анализирует его, чтобы преобразовать в байт-код на Python, который затем будет выполнен. Интерпретатор обнаружит любой недопустимый синтаксис в Python на этом первом этапе выполнения программы, также известном как этап синтаксического анализа. Если интерпретатор не может успешно проанализировать ваш код на Python, это означает, что где-то в вашем коде вы использовали недопустимый синтаксис. Интерпретатор попытается показать вам, где произошла эта ошибка.
Когда вы впервые изучаете Python, получение SyntaxError
может вызвать разочарование. Python попытается помочь вам определить, где в вашем коде недопустимый синтаксис, но обратная связь , которую он предоставляет, может немного сбить с толку. Иногда код, на который он указывает, совершенно исправен.
Примечание: Если ваш код синтаксически корректен, то могут возникнуть другие исключения, которые не являются SyntaxError
. Чтобы узнать больше о других исключениях Python и о том, как с ними обращаться, ознакомьтесь с Исключениями Python: Введение.
Вы не можете обрабатывать недопустимый синтаксис в Python, как другие исключения. Даже если вы попытаетесь обернуть блоки try
и except
вокруг кода с недопустимым синтаксисом, вы все равно увидите, что интерпретатор выдает ошибку SyntaxError
.
SyntaxError
Исключение и обратная трассировка
Когда интерпретатор обнаруживает недопустимый синтаксис в коде Python, он генерирует SyntaxError
исключение и предоставляет обратную трассировку с некоторой полезной информацией, которая поможет вам отладить ошибку. Вот некоторый код, содержащий недопустимый синтаксис в Python:
1# theofficefacts.py
2ages = {
3 'pam': 24,
4 'jim': 24
5 'michael': 43
6}
7print(f'Michael is {ages["michael"]} years old.')
Вы можете увидеть недопустимый синтаксис в словаре в строке 4. Во второй записи, 'jim'
, отсутствует запятая. Если бы вы попытались запустить этот код как есть, то получили бы следующую обратную трассировку:
$ python theofficefacts.py
File "theofficefacts.py", line 5
'michael': 43
^
SyntaxError: invalid syntax
Обратите внимание, что сообщение обратной трассировки указывает на ошибку в строке 5, а не в строке 4. Интерпретатор Python пытается указать, где находится недопустимый синтаксис. Однако на самом деле он может указать только на то, где он впервые заметил проблему. Когда вы получите результат обратной трассировки SyntaxError
и код, на который указывает обратная трассировка, будет выглядеть нормально, вам захочется начать просмотр кода в обратном порядке, пока вы не сможете определить, что не так.
В приведенном выше примере нет проблем с пропуском запятой, в зависимости от того, что следует за ней. Например, нет проблем с пропущенной запятой после 'michael'
в строке 5. Но как только интерпретатор сталкивается с чем-то, что не имеет смысла, он может только указать вам на первое, что он обнаружил и чего не смог понять.
Примечание: В этом руководстве предполагается, что вы знакомы с основами трассировки Python. Чтобы узнать больше об обратной трассировке Python и о том, как ее читать, ознакомьтесь с разделами Понимание обратной трассировки Python и Как получить максимальную отдачу от обратной трассировки Python.
Существует несколько элементов обратной трассировки SyntaxError
, которые могут помочь вам определить, где в вашем коде используется недопустимый синтаксис:
- Имя файла, в котором был обнаружен недопустимый синтаксис
- Номер строки и воспроизведенная строка кода, в которой была обнаружена проблема
- Символ курсора (
^
) в строке под воспроизведенным кодом, который показывает точку в коде, содержащую проблему - Сообщение об ошибке, появляющееся после типа исключения
SyntaxError
, которое может предоставить информацию, помогающую определить проблему
В приведенном выше примере указано имя файла theofficefacts.py
, номер строки равен 5, а курсор указывает на заключительную кавычку словарного ключа michael
. Обратная трассировка SyntaxError
может и не указывать на реальную проблему, но она укажет на первое место, где интерпретатор не смог разобраться в синтаксисе.
Есть еще два исключения, которые могут возникнуть в Python. Они эквивалентны SyntaxError
, но имеют разные названия:
IndentationError
TabError
Оба эти исключения наследуются от класса SyntaxError
, но это особые случаи, когда речь идет об отступах. Значение IndentationError
указывается, когда уровни отступов в вашем коде не совпадают. Значение TabError
указывается, когда в вашем коде используются как символы табуляции, так и пробелы в одном и том же файле. Более подробно эти исключения будут рассмотрены в следующем разделе.
Распространенные синтаксические проблемы
Когда вы впервые сталкиваетесь с SyntaxError
, полезно знать, в чем причина проблемы и что вы можете сделать, чтобы исправить недопустимый синтаксис в вашем коде на Python. В следующих разделах вы увидите некоторые из наиболее распространенных причин, по которым может возникать SyntaxError
, и способы их устранения.
Неправильное использование оператора присваивания (=
)
В Python есть несколько случаев, когда вы не можете выполнять присваивания объектам. Некоторые примеры относятся к присваиванию литералам и вызовам функций. В приведенном ниже блоке кода вы можете увидеть несколько примеров, которые пытаются это сделать, и результирующие SyntaxError
обратных трассировок:
>>> len('hello') = 5
File "<stdin>", line 1
SyntaxError: can't assign to function call
>>> 'foo' = 1
File "<stdin>", line 1
SyntaxError: can't assign to literal
>>> 1 = 'foo'
File "<stdin>", line 1
SyntaxError: can't assign to literal
В первом примере делается попытка присвоить значение 5
вызову len()
. Сообщение SyntaxError
в этом случае очень полезно. Это говорит вам о том, что вы не можете присвоить значение вызову функции.
Во втором и третьем примерах делается попытка присвоить литералам строку и целое число. То же правило справедливо и для других литеральных значений. И снова сообщения обратной трассировки указывают на то, что проблема возникает при попытке присвоить значение литералу.
Примечание: В приведенных выше примерах отсутствуют повторяющаяся строка кода и символ курсора (^
), указывающие на проблему в обратной трассировке. Исключение и обратная трассировка, которые вы видите, будут отличаться, когда вы находитесь в REPL и пытаетесь выполнить этот код из файла. Если бы этот код был в файле, вы бы получили повторяющуюся строку кода и символ курсора, указывающие на проблему, как вы видели в других случаях на протяжении всего этого руководства.
Вероятно, в ваши намерения не входит присвоение значения литералу или вызову функции. Например, это может произойти, если вы случайно оставите дополнительный знак равенства (=
), что превратит присвоение в сравнение. Сравнение, как вы можете видеть ниже, было бы корректным:
>>> len('hello') == 5
True
В большинстве случаев, когда Python сообщает вам, что вы присваиваете что-то, чему нельзя присвоить, вы сначала можете захотеть проверить, чтобы убедиться, что оператор не должен быть Логическим выражением вместо этого. Вы также можете столкнуться с этой проблемой, когда пытаетесь присвоить значение ключевому слову в Python, о чем мы расскажем в следующем разделе.
Орфографические ошибки, пропуски или неправильное использование ключевых слов Python
Ключевые слова Python - это набор защищенных слов, которые имеют особое значение в Python. Это слова, которые вы не можете использовать в качестве идентификаторов, переменных или имен функций в вашем коде. Они являются частью языка и могут использоваться только в том контексте, который разрешен Python.
Существует три распространенных способа ошибочного использования ключевых слов:
- Ошибка в написании ключевого слова
- Отсутствует ключевое слово
- Неправильное использование ключевого слова
Если вы допустили ошибку в написании ключевого слова в вашем коде на Python, то получите SyntaxError
. Например, вот что произойдет, если вы неправильно напишете ключевое слово for
:
>>> fro i in range(10):
File "<stdin>", line 1
fro i in range(10):
^
SyntaxError: invalid syntax
В сообщении указано SyntaxError: invalid syntax
, но это не очень помогает. Обратная трассировка указывает на первое место, где Python мог обнаружить, что что-то не так. Чтобы исправить такого рода ошибки, убедитесь, что все ваши ключевые слова в Python написаны правильно.
Другая распространенная проблема с ключевыми словами заключается в том, что вы полностью пропускаете их:
>>> for i range(10):
File "<stdin>", line 1
for i range(10):
^
SyntaxError: invalid syntax
Опять же, сообщение об исключении не очень полезно, но обратная трассировка действительно пытается направить вас в правильном направлении. Если вы вернетесь от курсора назад, то увидите, что ключевое слово in
отсутствует в синтаксисе for
loop.
Вы также можете неправильно использовать защищенное ключевое слово Python. Помните, что ключевые слова разрешено использовать только в определенных ситуациях. Если вы используете их неправильно, в вашем коде Python будет недопустимый синтаксис. Распространенным примером этого является использование continue
или break
вне цикла. Это может легко произойти во время разработки, когда вы что-то реализуете и случайно выводите логику за пределы цикла:
>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
... print('jim found')
... break
...
File "<stdin>", line 3
SyntaxError: 'break' outside loop
>>> if 'jim' in names:
... print('jim found')
... continue
...
File "<stdin>", line 3
SyntaxError: 'continue' not properly in loop
Здесь Python отлично справляется с тем, чтобы точно указать вам, что не так. Сообщения "'break' outside loop"
и "'continue' not properly in loop"
помогут вам точно понять, что делать. Если бы этот код был в файле, то в Python также было бы курсор, указывающий прямо на неправильно используемое ключевое слово.
Другой пример - если вы попытаетесь присвоить переменной ключевое слово Python или использовать ключевое слово для определения функции:
>>> pass = True
File "<stdin>", line 1
pass = True
^
SyntaxError: invalid syntax
>>> def pass():
File "<stdin>", line 1
def pass():
^
SyntaxError: invalid syntax
При попытке присвоить значение pass
, или при попытке определить новую функцию с именем pass
, вы получите SyntaxError
и снова просмотрите сообщение "invalid syntax"
.
Возможно, будет немного сложнее устранить этот тип недопустимого синтаксиса в коде Python, потому что снаружи код выглядит нормально. Если ваш код выглядит хорошо, но вы по-прежнему получаете SyntaxError
, то вы можете подумать о том, чтобы сверить имя переменной или функции, которые вы хотите использовать, со списком ключевых слов для используемой вами версии Python.
Список защищенных ключевых слов менялся с каждой новой версией Python. Например, в Python 3.6 вы могли бы использовать await
в качестве имени переменной или функции, но начиная с Python 3.7 это слово было добавлено в список ключевых слов. Теперь, если вы попытаетесь использовать await
в качестве имени переменной или функции, это приведет к появлению SyntaxError
, если ваш код для Python 3.7 или более поздней версии.
Другим примером этого является print
, который отличается в Python 2 от Python 3:
Version | print Type |
Takes A Value |
---|---|---|
Python 2 | keyword | нет |
Python 3 | built-in function | да |
print
это ключевое слово в Python 2, поэтому вы не можете присвоить ему значение. В Python 3, однако, это встроенная функция, которой можно присваивать значения.
Вы можете запустить следующий код, чтобы просмотреть список ключевых слов в любой версии Python, которую вы используете:
import keyword
print(keyword.kwlist)
keyword
также содержит полезный keyword.iskeyword()
. Если вам просто нужен быстрый способ проверить переменную pass
, то вы можете использовать следующий однострочный код:
>>> import keyword; keyword.iskeyword('pass')
True
Этот код быстро сообщит вам, является ли идентификатор, который вы пытаетесь использовать, ключевым словом или нет.
Пропущенные круглые скобки и кавычки
Часто причиной некорректного синтаксиса в коде на Python является пропущенная или неправильно подобранная закрывающая скобка или кавычка в кавычках. Их может быть трудно обнаружить в очень длинных строках вложенных круглых скобок или в более длинных многострочных блоках. Вы можете обнаружить несоответствующие или отсутствующие кавычки с помощью обратных ссылок Python:
>>> message = 'don't'
File "<stdin>", line 1
message = 'don't'
^
SyntaxError: invalid syntax
Здесь обратная трассировка указывает на недопустимый код, в котором после закрывающей одинарной кавычки стоит t'
. Чтобы исправить это, вы можете внести одно из двух изменений:
- Экранируйте одинарную кавычку обратной косой чертой (
'don\'t'
) - Вместо этого заключите всю строку в двойные кавычки (
"don't"
)
Еще одна распространенная ошибка - забыть закрыть строку. Как для строк, заключенных в двойные, так и в одинарные кавычки, ситуация и обратная трассировка одинаковы:
>>> message = "This is an unclosed string
File "<stdin>", line 1
message = "This is an unclosed string
^
SyntaxError: EOL while scanning string literal
На этот раз символ курсора в обратной трассировке указывает прямо на код проблемы. Сообщение SyntaxError
, "EOL while scanning string literal"
, немного более конкретное и помогает определить проблему. Это означает, что интерпретатор Python добрался до конца строки (EOL) до того, как открытая строка была закрыта. Чтобы исправить это, закройте строку кавычкой, которая соответствует той, которую вы использовали для ее начала. В данном случае это была бы двойная кавычка ("
).
Отсутствие кавычек в операторах внутри f-строки также может привести к недопустимому синтаксису в Python:
1# theofficefacts.py
2ages = {
3 'pam': 24,
4 'jim': 24,
5 'michael': 43
6}
7print(f'Michael is {ages["michael]} years old.')
Здесь в ссылке на словарь ages
внутри напечатанной f-строки отсутствует заключительная двойная кавычка в ссылке на ключ. В результате обратная трассировка выглядит следующим образом:
$ python theofficefacts.py
File "theofficefacts.py", line 7
print(f'Michael is {ages["michael]} years old.')
^
SyntaxError: f-string: unterminated string
Python идентифицирует проблему и сообщает вам, что она существует внутри f-строки. Сообщение "unterminated string"
также указывает, в чем проблема. Символ курсора в данном случае указывает только на начало f-строки.
Это может быть не так полезно, как когда курсор указывает на проблемную область f-строки, но это позволяет сузить область поиска. Где-то внутри этой f-строки есть незаконченная строка. Вам просто нужно выяснить, где именно. Чтобы устранить эту проблему, убедитесь, что все внутренние кавычки и скобки в f-строке присутствуют.
С пропущенными круглыми скобками ситуация в основном такая же. Если вы, например, опустите закрывающую квадратную скобку в списке , то Python обнаружит это и укажет на это. Однако есть несколько вариантов этого. Первый - убрать закрывающую скобку из списка:
# missing.py
def foo():
return [1, 2, 3
print(foo())
Когда вы запустите этот код, вам сообщат, что возникла проблема с вызовом print()
:
$ python missing.py
File "missing.py", line 5
print(foo())
^
SyntaxError: invalid syntax
Здесь происходит то, что Python считает, что список содержит три элемента: 1
, 2
, и 3 print(foo())
. Python использует пробел для логической группировки элементов, и поскольку нет запятой или скобок, отделяющих 3
от print(foo())
, Python объединяет их в качестве третьего элемента списка.
Другой вариант заключается в добавлении завершающей запятой после последнего элемента в списке, но без закрывающей квадратной скобки:
# missing.py
def foo():
return [1, 2, 3,
print(foo())
Теперь вы получаете другой результат отслеживания:
$ python missing.py
File "missing.py", line 6
^
SyntaxError: unexpected EOF while parsing
В предыдущем примере 3
и print(foo())
были объединены в один элемент, но здесь вы видите запятую, разделяющую их. Теперь вызов print(foo())
добавляется в качестве четвертого элемента списка, и Python достигает конца файла без закрывающей скобки. Обратная трассировка показывает, что Python добрался до конца файла (EOF), но ожидал чего-то другого.
В этом примере Python ожидал увидеть закрывающую скобку (]
), но повторяющаяся строка и символ курсора не очень помогают. Отсутствующие круглые скобки сложно идентифицировать в Python. Иногда единственное, что вы можете сделать, - это начать с курсора и двигаться назад, пока не сможете определить, чего не хватает или что не так.
Неправильный синтаксис словаря
Вы видели ранее, что вы могли бы получить SyntaxError
, если не ставить запятую в элементе словаря. Другой формой недопустимого синтаксиса в словарях Python является использование знака равенства (=
) для разделения ключей и значений вместо двоеточия:
>>> ages = {'pam'=24}
File "<stdin>", line 1
ages = {'pam'=24}
^
SyntaxError: invalid syntax
И снова это сообщение об ошибке не очень полезно. Однако повторяющаяся строка и курсор очень полезны! Они указывают прямо на проблемный символ.
Проблема такого типа часто возникает, если вы путаете синтаксис Python с синтаксисом других языков программирования. Вы также столкнетесь с этим, если перепутаете процесс определения словаря с вызовом dict()
. Чтобы исправить это, вы могли бы заменить знак равенства двоеточием. Вы также можете переключиться на использование dict()
:
>>> ages = dict(pam=24)
>>> ages
{'pam': 24}
Вы можете использовать dict()
для определения словаря, если такой синтаксис более полезен.
Используется неправильный отступ
Существует два подкласса SyntaxError
, которые конкретно касаются проблем с отступами:
IndentationError
TabError
В то время как другие языки программирования используют фигурные скобки для обозначения блоков кода, Python использует пробел. Это означает, что Python ожидает, что пробелы в вашем коде будут вести себя предсказуемо. Это вызовет ошибку IndentationError
если в блоке кода есть строка с неправильным количеством пробелов:
1# indentation.py
2def foo():
3 for i in range(10):
4 print(i)
5 print('done')
6
7foo()
Это может быть сложно увидеть, но в строке 5 отступ составляет всего 2 пробела. Это должно соответствовать инструкции цикла for
, которая находится на 4 пробела дальше. К счастью, Python легко распознает это и быстро сообщит вам, в чем проблема.
Однако здесь также есть некоторая двусмысленность. Предназначена ли строка print('done')
для после цикла for
или внутри цикла for
блокировка цикла? Когда вы запустите приведенный выше код, вы увидите следующую ошибку:
$ python indentation.py
File "indentation.py", line 5
print('done')
^
IndentationError: unindent does not match any outer indentation level
Несмотря на то, что обратная трассировка очень похожа на SyntaxError
, на самом деле это IndentationError
. Сообщение об ошибке также очень полезно. Это говорит о том, что уровень отступа в строке не соответствует никакому другому уровню отступа. Другими словами, print('done')
имеет отступ в 2 пробела, но Python не может найти ни одной другой строки кода, которая соответствовала бы этому уровню отступа. Вы можете быстро исправить это, убедившись, что код соответствует ожидаемому уровню отступов.
Другой тип SyntaxError
- это TabError
,, который вы увидите всякий раз, когда в строке есть символы табуляции или пробелы для отступа, в то время как остальная часть файла содержит другие символы. Это может оставаться скрытым до тех пор, пока Python не укажет вам на это!
Если ширина вашего табулятора равна количеству пробелов на каждом уровне отступа, то может показаться, что все строки расположены на одном уровне. Однако, если одна строка имеет отступ с использованием пробелов, а другая - с помощью табуляции, то Python укажет на это как на проблему:
1# indentation.py
2def foo():
3 for i in range(10):
4 print(i)
5 print('done')
6
7foo()
Здесь строка 5 имеет отступ в виде табуляции вместо 4 пробелов. Этот блок кода может показаться вам идеальным, а может и совершенно неправильным, в зависимости от настроек вашей системы.
Однако Python немедленно заметит проблему. Но прежде чем вы запустите код, чтобы посмотреть, что, по мнению Python, неверно, вам может быть полезно посмотреть пример того, как выглядит код при разных настройках ширины табуляции:
$ tabs 4 # Sets the shell tab width to 4 spaces
$ cat -n indentation.py
1 # indentation.py
2 def foo():
3 for i in range(10)
4 print(i)
5 print('done')
6
7 foo()
$ tabs 8 # Sets the shell tab width to 8 spaces (standard)
$ cat -n indentation.py
1 # indentation.py
2 def foo():
3 for i in range(10)
4 print(i)
5 print('done')
6
7 foo()
$ tabs 3 # Sets the shell tab width to 3 spaces
$ cat -n indentation.py
1 # indentation.py
2 def foo():
3 for i in range(10)
4 print(i)
5 print('done')
6
7 foo()
Обратите внимание на разницу в отображении между тремя приведенными выше примерами. В большинстве случаев в коде используется по 4 пробела для каждого уровня отступа, но в строке 5 во всех трех примерах используется одна табуляция. Ширина вкладки изменяется в зависимости от параметра ширина вкладки:
- Если ширина табуляции равна 4, то оператор
print
будет выглядеть так, как будто он находится вне циклаfor
. Консоль выведет'done'
в конце цикла. - Если ширина табуляции равна 8, что является стандартным для многих систем, то оператор
print
будет выглядеть так, как будто он находится внутри циклаfor
. Консоль будет выводить'done'
после каждого числа. - Если ширина табуляции равна 3, то оператор
print
выглядит неуместным. В этом случае строка 5 не соответствует ни одному уровню отступа.
Когда вы запустите код, вы получите следующую ошибку и обратную трассировку:
$ python indentation.py
File "indentation.py", line 5
print('done')
^
TabError: inconsistent use of tabs and spaces in indentation
Обратите внимание на TabError
вместо обычного SyntaxError
. Python указывает на проблемную строку и выдает полезное сообщение об ошибке. Это ясно говорит вам о том, что в одном и том же файле для отступов используются различные символы табуляции и пробелы.
Решение этой проблемы состоит в том, чтобы заставить все строки в одном и том же файле кода Python использовать либо табуляцию, либо пробелы, но не то и другое сразу. Для приведенных выше блоков кода исправлением было бы удалить табуляцию и заменить ее 4 пробелами, которые будут выводить 'done'
после завершения цикла for
.
Определение и вызов функций
Вы можете столкнуться с недопустимым синтаксисом в Python при определении или вызове функций. Например, вы увидите SyntaxError
, если используете точку с запятой вместо двоеточия в конце определения функции:
>>> def fun();
File "<stdin>", line 1
def fun();
^
SyntaxError: invalid syntax
Обратная трассировка здесь очень полезна, так как курсор указывает прямо на проблемный символ. Вы можете устранить этот недопустимый синтаксис в Python, заменив точку с запятой на двоеточие.
Кроме того, аргументы ключевых слов как в определениях функций, так и в вызовах функций должны располагаться в правильном порядке. Аргументы с ключевыми словами всегда следуют после позиционных аргументов. Несоблюдение этого порядка приведет к SyntaxError
:
>>> def fun(a, b):
... print(a, b)
...
>>> fun(a=1, 2)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
Здесь, опять же, сообщение об ошибке очень полезно для того, чтобы точно сказать вам, что не так со строкой.
Изменение версий Python
Иногда код, который отлично работает в одной версии Python, выходит из строя в более новой версии. Это связано с официальными изменениями в синтаксисе языка. Наиболее известным примером этого является оператор print
, который превратился из ключевого слова в Python 2 во встроенную функцию в Python 3:
>>> # Valid Python 2 syntax that fails in Python 3
>>> print 'hello'
File "<stdin>", line 1
print 'hello'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello')?
Это один из примеров, когда отображается сообщение об ошибке, содержащее SyntaxError
! Он не только сообщает вам, что в вызове print
пропущены круглые скобки, но и предоставляет правильный код, который поможет вам исправить инструкцию.
Еще одна проблема, с которой вы можете столкнуться, - это когда вы читаете или изучаете синтаксис, который является допустимым в более новой версии Python, но недопустим в той версии, в которой вы пишете. Примером этого является синтаксис f-string, который не существует в версиях Python до 3.6:
>>> # Any version of python before 3.6 including 2.7
>>> w ='world'
>>> print(f'hello, {w}')
File "<stdin>", line 1
print(f'hello, {w}')
^
SyntaxError: invalid syntax
В версиях Python до 3.6 интерпретатор ничего не знает о синтаксисе f-строки и просто выдает общее сообщение "invalid syntax"
. Проблема в данном случае заключается в том, что код выглядит совершенно нормально, но он был запущен с более старой версией Python. Если вы сомневаетесь, перепроверьте, какую версию Python вы используете!
Синтаксис Python продолжает развиваться, и в Python появилось несколько интересных новых функций 3.8:
- Оператор Walrus (выражения присваивания)
- Синтаксис F-строки для отладки
- Аргументы только для позиции
Если вы хотите опробовать некоторые из этих новых функций, вам нужно убедиться, что вы работаете в среде Python 3.8. В противном случае вы получите SyntaxError
.
Python 3.8 также предоставляет новый SyntaxWarning
. Вы увидите это предупреждение в ситуациях, когда синтаксис корректен, но все еще выглядит подозрительно. Примером этого может служить ситуация, когда вы пропускаете запятую между двумя кортежами в списке. Это был бы допустимый синтаксис в версиях Python до 3.8, но код вызвал бы TypeError
, потому что кортеж не может быть вызван:
>>> [(1,2)(2,3)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
Это TypeError
означает, что вы не можете вызвать кортеж как функцию, что, по мнению интерпретатора Python, вы и делаете.
В Python 3.8 этот код по-прежнему вызывает TypeError
, но теперь вы также увидите SyntaxWarning
, который указывает, как вы можете устранить проблему:
>>> [(1,2)(2,3)]
<stdin>:1: SyntaxWarning: 'tuple' object is not callable; perhaps you missed a comma?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
Полезное сообщение, сопровождающее новый SyntaxWarning
, даже содержит подсказку ("perhaps you missed a comma?"
), которая укажет вам правильное направление!
Заключение
В этом руководстве вы увидели, какую информацию дает вам обратная трассировка SyntaxError
. Вы также ознакомились со многими распространенными примерами недопустимого синтаксиса в Python и с решениями этих проблем. Это не только ускорит ваш рабочий процесс, но и сделает вас более полезным специалистом по проверке кода!
Когда вы пишете код, старайтесь использовать IDE, которая понимает синтаксис Python и обеспечивает обратную связь. Если вы поместите многие неверные примеры кода на Python из этого руководства в хорошую среду IDE, то они должны выделить проблемные строки еще до того, как вы приступите к выполнению своего кода.
Получение SyntaxError
во время изучения Python может вызывать разочарование, но теперь вы знаете, как понимать сообщения обратной трассировки и с какими формами недопустимого синтаксиса в Python вы можете столкнуться . В следующий раз, когда вы получите оценку SyntaxError
, у вас будет больше возможностей быстро устранить проблему!