锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / 语音识别开源 / python中的Invalid Syntax和SyntaxError常见原因

联系方式

固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

服务方向

人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发

python中的Invalid Syntax和SyntaxError常见原因


背景

近期用python开发小项目,代码用python3.6开发,但客户环境是python2.4,向下兼容比较难,遇到了些不常见错误,比如下图:python_invalidsyntax
最终发现是python2.4不支持with关键字,去掉with就解决了问题,下面是从国外网站上找的更多线索,供大家学习提高。

 

Python is known for its simple syntax. However, when you’re learning Python for the first time or when you’ve come to Python with a solid background in another programming language, you may run into some things that Python doesn’t allow. If you’ve ever received a SyntaxError when trying to run your Python code, then this guide can help you. Throughout this tutorial, you’ll see common examples of invalid syntax in Python and learn how to resolve the issue. Python以其简单的语法而闻名。但是,当您第一次学习Python时,或者您以另一种编程语言扎扎实实地学习Python时,可能会遇到一些Python不允许的事情。如果您在尝试运行Python代码时收到过SyntaxError错误,那么本指南可以为您提供帮助。在整个教程中,您将看到Python中无效语法的常见示例,并了解如何解决该问题。

By the end of this tutorial, you’ll be able to: 在本教程结束时,您将能够:

Identify invalid syntax in Python 识别Python中的无效语法
Make sense of SyntaxError tracebacks 了解SyntaxError追溯
Resolve invalid syntax or prevent it altogether 解决无效的语法或完全防止语法
Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level. 免费奖金:关于Python精通的5个想法,这是针对Python开发人员的免费课程,向您展示了将Python技能提升到新水平所需的路线图和思路。

Invalid Syntax in Python Python中的无效语法

When you run your Python code, the interpreter will first parse it to convert it into Python byte code, which it will then execute. The interpreter will find any invalid syntax in Python during this first stage of program execution, also known as the parsing stage. If the interpreter can’t parse your Python code successfully, then this means that you used invalid syntax somewhere in your code. The interpreter will attempt to show you where that error occurred. 当您运行Python代码时,解释器将首先对其进行解析,以将其转换为Python字节代码,然后执行该代码。在程序执行的第一阶段(也称为解析阶段),解释器将在Python中找到任何无效的语法。如果解释器无法成功解析您的Python代码,则意味着您在代码中的某处使用了无效的语法。解释器将尝试向您显示该错误发生的位置。

When you’re learning Python for the first time, it can be frustrating to get a SyntaxError. Python will attempt to help you determine where the invalid syntax is in your code, but the traceback it provides can be a little confusing. Sometimes, the code it points to is perfectly fine. 第一次学习Python时,遇到SyntaxError可能会令人沮丧。 Python将尝试帮助您确定无效语法在代码中的位置,但是它提供的回溯可能会有些混乱。有时,它指向的代码非常正确。

Note: If your code is syntactically correct, then you may get other exceptions raised that are not a SyntaxError. To learn more about Python’s other exceptions and how to handle them, check out Python Exceptions: An Introduction. 注意:如果您的代码在语法上是正确的,则可能会引发不是SyntaxError的其他异常。要了解有关Python其他异常以及如何处理它们的更多信息,请查看Python异常:简介。

You can’t handle invalid syntax in Python like other exceptions. Even if you tried to wrap a try and except block around code with invalid syntax, you’d still see the interpreter raise a SyntaxError. 您无法像其他例外一样处理Python中的无效语法。即使您尝试使用无效的语法在代码中包装try和except块,您仍然会看到解释器引发SyntaxError。

SyntaxError Exception and Traceback SyntaxError异常和回溯

When the interpreter encounters invalid syntax in Python code, it will raise a SyntaxError exception and provide a traceback with some helpful information to help you debug the error. Here’s some code that contains invalid syntax in Python: 当解释器在Python代码中遇到无效语法时,它将引发SyntaxError异常,并提供一些有用信息的回溯,以帮助您调试错误。这是一些在Python中包含无效语法的代码:

# theofficefacts.py
ages = {
'pam': 24,
'jim': 24
'michael': 43
}
print(f'Michael is {ages["michael"]} years old.')

You can see the invalid syntax in the dictionary literal on line 4. The second entry, 'jim', is missing a comma. If you tried to run this code as-is, then you’d get the following traceback: 您可以在第4行的字典文字中看到无效的语法。第二个条目'jim'缺少逗号。如果您尝试按原样运行此代码,则将获得以下回溯:

$ python theofficefacts.py
File "theofficefacts.py", line 5
'michael': 43
^
SyntaxError: invalid syntax

Note that the traceback message locates the error in line 5, not line 4. The Python interpreter is attempting to point out where the invalid syntax is. However, it can only really point to where it first noticed a problem. When you get a SyntaxError traceback and the code that the traceback is pointing to looks fine, then you’ll want to start moving backward through the code until you can determine what’s wrong. 请注意,traceback消息在第5行而不是第4行中定位错误。Python解释器试图指出无效语法的位置。但是,它只能真正指出最初发现问题的地方。当您收到SyntaxError追溯,并且追溯指向的代码看起来不错时,您将希望开始向后浏览代码,直到确定出什么问题为止。

In the example above, there isn’t a problem with leaving out a comma, depending on what comes after it. For example, there’s no problem with a missing comma after 'michael' in line 5. But once the interpreter encounters something that doesn’t make sense, it can only point you to the first thing it found that it couldn’t understand. 在上面的示例中,根据逗号后面的内容,省略逗号是没有问题的。例如,在第5行中的“迈克尔”后面没有逗号丢失没有问题,但是一旦解释器遇到了没有意义的内容,它只会将您指向它发现无法理解的第一件事。

Note: This tutorial assumes that you know the basics of Python’s tracebacks. To learn more about the Python traceback and how to read them, check out Understanding the Python Traceback and Getting the Most out of a Python Traceback. 注意:本教程假设您了解Python的回溯基础。要了解有关Python追溯以及如何阅读它们的更多信息,请查看“了解Python追溯”并充分利用Python追溯。

There are a few elements of a SyntaxError traceback that can help you determine where the invalid syntax is in your code: SyntaxError跟踪的一些元素可以帮助您确定无效语法在代码中的位置:

The file name where the invalid syntax was encountered 遇到无效语法的文件名
The line number and reproduced line of code where the issue was encountered 遇到问题的行号和复制的代码行
A caret (^) on the line below the reproduced code, which shows you the point in the code that has a problem 复制的代码下面一行的插入符号(^),向您显示代码中有问题的点
The error message that comes after the exception type SyntaxError, which can provide information to help you determine the problem 异常类型SyntaxError后出现的错误消息,该错误消息可以提供信息以帮助您确定问题
In the example above, the file name given was theofficefacts.py, the line number was 5, and the caret pointed to the closing quote of the dictionary key michael. The SyntaxError traceback might not point to the real problem, but it will point to the first place where the interpreter couldn’t make sense of the syntax. 在上面的示例中,给定的文件名为theofficefacts.py,行号为5,插入符号指向字典键michael的右引号。 SyntaxError追溯可能并不指向真正的问题,但它将指向解释器无法理解语法的第一个位置。

There are two other exceptions that you might see Python raise. These are equivalent to SyntaxError but have different names: 您可能会看到Python引发了另外两个例外。这些等效于SyntaxError,但具有不同的名称:

IndentationError IndentationError
TabError TabError
These exceptions both inherit from the SyntaxError class, but they’re special cases where indentation is concerned. An IndentationError is raised when the indentation levels of your code don’t match up. A TabError is raised when your code uses both tabs and spaces in the same file. You’ll take a closer look at these exceptions in a later section. 这些异常都继承自SyntaxError类,但在涉及缩进的特殊情况下。当代码的缩进级别不匹配时,会引发IndentationError。当您的代码在同一文件中同时使用制表符和空格时,将引发TabError。您将在后面的部分中仔细研究这些例外情况。

Common Syntax Problems 常见语法问题

When you encounter a SyntaxError for the first time, it’s helpful to know why there was a problem and what you might do to fix the invalid syntax in your Python code. In the sections below, you’ll see some of the more common reasons that a SyntaxError might be raised and how you can fix them. 首次遇到SyntaxError时,了解为什么会出现问题以及如何解决Python代码中的无效语法会很有帮助。在以下各节中,您将看到可能引发SyntaxError的一些较常见的原因,以及如何解决它们。

Misusing the Assignment Operator (=) 错用分配运算符(=)

There are several cases in Python where you’re not able to make assignments to objects. Some examples are assigning to literals and function calls. In the code block below, you can see a few examples that attempt to do this and the resulting SyntaxError tracebacks: 在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

The first example tries to assign the value 5 to the len() call. The SyntaxError message is very helpful in this case. It tells you that you can’t assign a value to a function call. 第一个示例尝试将值5分配给len()调用。在这种情况下,SyntaxError消息非常有用。它告诉您不能为函数调用分配值。

The second and third examples try to assign a string and an integer to literals. The same rule is true for other literal values. Once again, the traceback messages indicate that the problem occurs when you attempt to assign a value to a literal. 第二个和第三个示例尝试为文字分配一个字符串和一个整数。其他文字值也适用相同的规则。再次,回溯消息表明当您尝试将值分配给文字时出现问题。

Note: The examples above are missing the repeated code line and caret (^) pointing to the problem in the traceback. The exception and traceback you see will be different when you’re in the REPL vs trying to execute this code from a file. If this code were in a file, then you’d get the repeated code line and caret pointing to the problem, as you saw in other cases throughout this tutorial. 注意:上面的示例缺少重复的代码行和脱字符(^),它们指出了回溯中的问题。在REPL中与尝试从文件中执行此代码相比,您看到的异常和回溯会有所不同。如果此代码在文件中,那么您将得到重复的代码行,并在插入标记处指出问题,就像在本教程中其他情况下所看到的那样。

It’s likely that your intent isn’t to assign a value to a literal or a function call. For instance, this can occur if you accidentally leave off the extra equals sign (=), which would turn the assignment into a comparison. A comparison, as you can see below, would be valid: 您的意图可能不是为文字或函数调用分配值。例如,如果您不小心遗忘了多余的等号(=),则会发生这种情况,这会使分配成为比较。如您在下面看到的,比较是有效的:

>>> len('hello') == 5
True

Most of the time, when Python tells you that you’re making an assignment to something that can’t be assigned to, you first might want to check to make sure that the statement shouldn’t be a Boolean expression instead. You may also run into this issue when you’re trying to assign a value to a Python keyword, which you’ll cover in the next section. 在大多数情况下,当Python告诉您要对无法分配的内容进行赋值时,您首先可能要检查以确保该语句不应为布尔表达式。当您尝试为Python关键字分配值时,也可能会遇到此问题,这将在下一部分中介绍。

Misspelling, Missing, or Misusing Python Keywords 拼写错误,丢失或错用Python关键字

Python keywords are a set of protected words that have special meaning in Python. These are words you can’t use as identifiers, variables, or function names in your code. They’re a part of the language and can only be used in the context that Python allows. Python关键字是一组受保护的单词,在Python中具有特殊含义。这些是您不能在代码中用作标识符,变量或函数名称的词。它们是语言的一部分,只能在Python允许的上下文中使用。

There are three common ways that you can mistakenly use keywords: 您可能会错误使用关键字的三种常见方法:

Misspelling a keyword 拼写错误的关键字
Missing a keyword 缺少关键字
Misusing a keyword 错用关键字
If you misspell a keyword in your Python code, then you’ll get a SyntaxError. For example, here’s what happens if you spell the keyword for incorrectly: 如果您在Python代码中拼错了关键字,则会收到SyntaxError。例如,如果您将关键字拼写错误,将会发生以下情况:

>>> fro i in range(10):
File "<stdin>", line 1
fro i in range(10):
^
SyntaxError: invalid syntax

The message reads SyntaxError: invalid syntax, but that’s not very helpful. The traceback points to the first place where Python could detect that something was wrong. To fix this sort of error, make sure that all of your Python keywords are spelled correctly. 该消息显示为SyntaxError:语法无效,但这不是很有帮助。追溯指向Python可以检测到某些错误的第一个位置。要解决这种错误,请确保所有Python关键字的拼写正确。

Another common issue with keywords is when you miss them altogether: 关键字的另一个常见问题是当您完全错过关键字时:

>>> for i range(10):
File "<stdin>", line 1
for i range(10):
^
SyntaxError: invalid syntax

Once again, the exception message isn’t that helpful, but the traceback does attempt to point you in the right direction. If you move back from the caret, then you can see that the in keyword is missing from the for loop syntax. 再说一次,异常消息并没有那么大的帮助,但是回溯确实会试图指出正确的方向。如果从插入符移回,则可以看到for循环语法中缺少in关键字。

You can also misuse a protected Python keyword. Remember, keywords are only allowed to be used in specific situations. If you use them incorrectly, then you’ll have invalid syntax in your Python code. A common example of this is the use of continue or break outside of a loop. This can easily happen during development when you’re implementing things and happen to move logic outside of a 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

Here, Python does a great job of telling you exactly what’s wrong. The messages "'break' outside loop" and "'continue' not properly in loop" help you figure out exactly what to do. If this code were in a file, then Python would also have the caret pointing right to the misused keyword. 在这里,Python可以很好地告诉您确切的错误。消息“'打破'外部循环”和“'继续'循环不正确”可帮助您准确地确定要做什么。如果此代码位于文件中,则Python还将插入符号指向正确使用的关键字。

Another example is if you attempt to assign a Python keyword to a variable or use a keyword to define a function: 另一个示例是,如果您尝试将Python关键字分配给变量或使用关键字定义函数:

>>> pass = True
File "<stdin>", line 1
pass = True
^
SyntaxError: invalid syntax >>> def pass():
File "<stdin>", line 1
def pass():
^
SyntaxError: invalid syntax

When you attempt to assign a value to pass, or when you attempt to define a new function called pass, you’ll get a SyntaxError and see the "invalid syntax" message again. 当您尝试分配要传递的值或尝试定义一个名为pass的新函数时,您会收到SyntaxError并再次看到“无效语法”消息。

It might be a little harder to solve this type of invalid syntax in Python code because the code looks fine from the outside. If your code looks good, but you’re still getting a SyntaxError, then you might consider checking the variable name or function name you want to use against the keyword list for the version of Python that you’re using. 在Python代码中解决这种类型的无效语法可能会有些困难,因为从外部看,代码看起来不错。如果您的代码看起来不错,但仍然出现SyntaxError,则可以考虑针对要使用的Python版本的关键字列表,检查要使用的变量名或函数名。

The list of protected keywords has changed with each new version of Python. For example, in Python 3.6 you could use await as a variable name or function name, but as of Python 3.7, that word has been added to the keyword list. Now, if you try to use await as a variable or function name, this will cause a SyntaxError if your code is for Python 3.7 or later. 每个新版本的Python都更改了受保护关键字的列表。例如,在Python 3.6中,您可以将await用作变量名或函数名,但是从Python 3.7开始,该词已添加到关键字列表中。现在,如果您尝试将await用作变量或函数名,那么如果您的代码用于Python 3.7或更高版本,这将导致SyntaxError。

Another example of this is print, which differs in Python 2 vs Python 3: 另一个例子是print,在Python 2和Python 3中有所不同。

Version print Type Takes A Value 版本 print类型 取值
Python 2 keyword no Python 2 关键字 否
Python 3 built-in function yes Python 3 内置函数 yes
print is a keyword in Python 2, so you can’t assign a value to it. In Python 3, however, it’s a built-in function that can be assigned values. print是Python 2中的关键字,因此您无法为其分配值。但是,在Python 3中,它是一个内置函数,可以为其分配值。

You can run the following code to see the list of keywords in whatever version of Python you’re running: 您可以运行以下代码,以查看所运行的任何版本的Python中的关键字列表:

import keyword
print(keyword.kwlist)

keyword also provides the useful keyword.iskeyword(). If you just need a quick way to check the pass variable, then you can use the following one-liner: 关键字还提供了有用的keyword.iskeyword()。如果您只需要一种快速的方法来检查pass变量,则可以使用以下单行代码:

>>> import keyword; keyword.iskeyword('pass')
True

This code will tell you quickly if the identifier that you’re trying to use is a keyword or not. 该代码将快速告诉您您要使用的标识符是否是关键字。

Missing Parentheses, Brackets, and Quotes 缺少括号,方括号和引号

Often, the cause of invalid syntax in Python code is a missed or mismatched closing parenthesis, bracket, or quote. These can be hard to spot in very long lines of nested parentheses or longer multi-line blocks. You can spot mismatched or missing quotes with the help of Python’s tracebacks: 通常,Python代码中语法无效的原因是右括号,方括号或引号丢失或不匹配。这些可能很难在很长的嵌套括号行或更长的多行块中发现。您可以借助Python的回溯发现不匹配或缺失的引号:

>>> message = 'don't'
File "<stdin>", line 1
message = 'don't'
^
SyntaxError: invalid syntax

Here, the traceback points to the invalid code where there’s a t' after a closing single quote. To fix this, you can make one of two changes: 在这里,回溯指向无效代码,在单引号后加一个t'。要解决此问题,您可以进行以下两项更改之一:

Escape the single quote with a backslash ('don\'t') 用反斜杠转义单引号('don \\'t')
Surround the entire string in double-quotes instead ("don't") 请将整个字符串用双引号引起来(“不要”)
Another common mistake is to forget to close string. With both double-quoted and single-quoted strings, the situation and traceback are the same: 另一个常见的错误是忘记关闭字符串。对于双引号和单引号字符串,情况和回溯是相同的:

>>> message = "This is an unclosed string
File "<stdin>", line 1
message = "This is an unclosed string
^
SyntaxError: EOL while scanning string literal

This time, the caret in the traceback points right to the problem code. The SyntaxError message, "EOL while scanning string literal", is a little more specific and helpful in determining the problem. This means that the Python interpreter got to the end of a line (EOL) before an open string was closed. To fix this, close the string with a quote that matches the one you used to start it. In this case, that would be a double quote ("). 这次,回溯中的插入符号直接指向问题代码。 SyntaxError消息“扫描字符串文字时会停产”会更加具体,有助于确定问题。这意味着在关闭打开的字符串之前,Python解释器到达了行尾(EOL)。要解决此问题,请用与引号相匹配的引号关闭该字符串。在这种情况下,它将是双引号(“)。

Quotes missing from statements inside an f-string can also lead to invalid syntax in Python: f字符串中的语句中缺少引号也可能导致Python中的语法无效:

# theofficefacts.py
ages = {
'pam': 24,
'jim': 24,
'michael': 43
}
print(f'Michael is {ages["michael]} years old.')

Here, the reference to the ages dictionary inside the printed f-string is missing the closing double quote from the key reference. The resulting traceback is as follows: 在这里,在打印的f字符串中对ages词典的引用缺少键引用中的右引号。结果回溯如下:

$ python theofficefacts.py
File "theofficefacts.py", line 7
print(f'Michael is {ages["michael]} years old.')
^
SyntaxError: f-string: unterminated string

Python identifies the problem and tells you that it exists inside the f-string. The message "unterminated string" also indicates what the problem is. The caret in this case only points to the beginning of the f-string. Python会识别出问题,并告诉您它存在于f字符串中。消息“未终止的字符串”还指示问题所在。在这种情况下,插入符号仅指向f字符串的开头。

This might not be as helpful as when the caret points to the problem area of the f-string, but it does narrow down where you need to look. There’s an unterminated string somewhere inside that f-string. You just have to find out where. To fix this problem, make sure that all internal f-string quotes and brackets are present. 这可能不如插入符号指向f弦的问题区域时有用,但是它确实缩小了您需要查找的位置。 F字符串中的某个地方有一个未终止的引号。您只需要找出位置。要解决此问题,请确保所有内部f字符串引号和方括号都存在。

The situation is mostly the same for missing parentheses and brackets. If you leave out the closing square bracket from a list, for example, then Python will spot that and point it out. There are a few variations of this, however. The first is to leave the closing bracket off of the list: 对于缺少括号和括号的情况,情况大致相同。例如,如果您从列表中省略了右方括号,那么Python将会发现并指出。但是,这有一些变体。首先是将右括号放在列表之外:

# missing.py
def foo():
return [1, 2, 3 print(foo())

When you run this code, you’ll be told that there’s a problem with the call to print(): 运行此代码时,系统会告诉您print()调用存在问题:

$ python missing.py
File "missing.py", line 5
print(foo())
^
SyntaxError: invalid syntax

What’s happening here is that Python thinks the list contains three elements: 1, 2, and 3 print(foo()). Python uses whitespace to group things logically, and because there’s no comma or bracket separating 3 from print(foo()), Python lumps them together as the third element of the list. 这里发生的是Python认为列表包含三个元素:1、2和3 print(foo())。 Python使用空格对内容进行逻辑分组,并且由于没有逗号或方括号将3与print(foo())分开,因此Python将它们集中在一起作为列表的第三个元素。

Another variation is to add a trailing comma after the last element in the list while still leaving off the closing square bracket: 另一个变体是在列表中的最后一个元素之后添加尾随逗号,同时仍保留右方括号:

# missing.py
def foo():
return [1, 2, 3, print(foo())

Now you get a different traceback: 现在您将获得不同的回溯:

$ python missing.py
File "missing.py", line 6 ^
SyntaxError: unexpected EOF while parsing

In the previous example, 3 and print(foo()) were lumped together as one element, but here you see a comma separating the two. Now, the call to print(foo()) gets added as the fourth element of the list, and Python reaches the end of the file without the closing bracket. The traceback tells you that Python got to the end of the file (EOF), but it was expecting something else. 在前面的示例中,将3和print(foo())集中在一起作为一个元素,但是在这里您看到用逗号分隔两者。现在,对print(foo())的调用被添加为列表的第四个元素,Python到达了文件的末尾而没有右括号。追溯告诉您Python到达了文件末尾(EOF),但是它期待其他内容。

In this example, Python was expecting a closing bracket (]), but the repeated line and caret are not very helpful. Missing parentheses and brackets are tough for Python to identify. Sometimes the only thing you can do is start from the caret and move backward until you can identify what’s missing or wrong. 在此示例中,Python期望使用右括号(]),但是重复的行和插入符号并不是很有用。缺少括号和括号对于Python来说很难识别。有时,您唯一可以做的就是从插入符号开始,然后向后移动,直到您可以确定缺失或错误的地方。

Mistaking Dictionary Syntax 错误的字典语法

You saw earlier that you could get a SyntaxError if you leave the comma off of a dictionary element. Another form of invalid syntax with Python dictionaries is the use of the equals sign (=) to separate keys and values, instead of the colon: 前面您看到,如果将逗号放在字典元素之外,则可能会出现SyntaxError。 Python字典的另一种无效语法形式是使用等号(=)来分隔键和值,而不是冒号:

>>> ages = {'pam'=24}
File "<stdin>", line 1
ages = {'pam'=24}
^
SyntaxError: invalid syntax

Once again, this error message is not very helpful. The repeated line and caret, however, are very helpful! They’re pointing right to the problem character. 再一次,此错误消息不是很有帮助。但是,重复的线条和插入符号非常有帮助!他们指的是问题角色。

This type of issue is common if you confuse Python syntax with that of other programming languages. You’ll also see this if you confuse the act of defining a dictionary with a dict() call. To fix this, you could replace the equals sign with a colon. You can also switch to using dict(): 如果您将Python语法与其他编程语言的语法混淆,则这种类型的问题很常见。如果您将定义字典的行为与dict()调用混淆,也会看到此信息。要解决此问题,您可以用冒号替换等号。您还可以切换到使用dict():

>>> ages = dict(pam=24)
>>> ages
{'pam': 24}

You can use dict() to define the dictionary if that syntax is more helpful. 如果该语法更有用,则可以使用dict()定义字典。

Using the Wrong Indentation 使用错误的缩进

There are two sub-classes of SyntaxError that deal with indentation issues specifically: 有两个SyntaxError子类专门处理缩进问题:

IndentationError IndentationError
TabError TabError
While other programming languages use curly braces to denote blocks of code, Python uses whitespace. That means that Python expects the whitespace in your code to behave predictably. It will raise an IndentationError if there’s a line in a code block that has the wrong number of spaces: 其他编程语言使用大括号表示代码块,而Python使用空格。这意味着Python期望代码中的空白行为可预测。如果代码块中一行的空格数错误,则会引发IndentationError:

# indentation.py
def foo():
for i in range(10):
print(i)
print('done') foo()

This might be tough to see, but line 5 is only indented 2 spaces. It should be in line with the for loop statement, which is 4 spaces over. Thankfully, Python can spot this easily and will quickly tell you what the issue is. 这可能很难看清,但是第5行仅缩进2个空格。它应与for循环语句相符,该语句超过4个空格。幸运的是,Python可以很容易地发现这一点,并且可以迅速告诉您问题所在。

There’s also a bit of ambiguity here, though. Is the print('done') line intended to be after the for loop or inside the for loop block? When you run the above code, you’ll see the following error: 不过,这里也有一些歧义。是print('done')行是在for循环之后还是在for循环块内?运行上面的代码时,您会看到以下错误:

$ python indentation.py
File "indentation.py", line 5
print('done')
^
IndentationError: unindent does not match any outer indentation level

Even though the traceback looks a lot like the SyntaxError traceback, it’s actually an IndentationError. The error message is also very helpful. It tells you that the indentation level of the line doesn’t match any other indentation level. In other words, print('done') is indented 2 spaces, but Python can’t find any other line of code that matches this level of indentation. You can fix this quickly by making sure the code lines up with the expected indentation level. 尽管回溯看起来很像SyntaxError回溯,但实际上是一个IndentationError。该错误消息也非常有帮助。它告诉您该行的缩进级别与任何其他缩进级别都不匹配。换句话说,print('done')缩进2个空格,但是Python找不到与此缩进级别相匹配的任何其他代码行。您可以通过确保代码与预期的缩进级别对齐来快速解决此问题。

The other type of SyntaxError is the TabError, which you’ll see whenever there’s a line that contains either tabs or spaces for its indentation, while the rest of the file contains the other. This might go hidden until Python points it out to you! SyntaxError的另一种类型是TabError,只要一行包含用于缩进的制表符或空格,而文件的其余部分包含另一行,您就会看到。这可能会隐藏起来,直到Python向您指出!

If your tab size is the same width as the number of spaces in each indentation level, then it might look like all the lines are at the same level. However, if one line is indented using spaces and the other is indented with tabs, then Python will point this out as a problem: 如果选项卡的大小与每个缩进级别中的空格数相同,那么看起来所有行都在同一级别。但是,如果一行使用空格缩进,另一行使用制表符缩进,则Python会指出此问题:

# indentation.py
def foo():
for i in range(10):
print(i)
print('done') foo()

Here, line 5 is indented with a tab instead of 4 spaces. This code block could look perfectly fine to you, or it could look completely wrong, depending on your system settings. 在这里,第5行缩进了一个制表符,而不是4个空格。根据您的系统设置,此代码块对您而言可能看起来很好,也可能看起来完全错误。

Python, however, will notice the issue immediately. But before you run the code to see what Python will tell you is wrong, it might be helpful for you to see an example of what the code looks like under different tab width settings: 但是,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()

Notice the difference in display between the three examples above. Most of the code uses 4 spaces for each indentation level, but line 5 uses a single tab in all three examples. The width of the tab changes, based on the tab width setting: 注意上面三个示例之间在显示上的差异。大多数代码为每个缩进级别使用4个空格,但是在所有三个示例中的第5行均使用单个选项卡。标签的宽度根据标签的宽度设置而变化:

If the tab width is 4, then the print statement will look like it’s outside the for loop. The console will print 'done' at the end of the loop. 如果制表符的宽度为4,则print语句将看起来像位于for循环之外。控制台将在循环结束时打印“完成”。
If the tab width is 8, which is standard for a lot of systems, then the print statement will look like it’s inside the for loop. The console will print 'done' after each number. 如果制表符宽度为8(这是许多系统的标准设置),则print语句将看起来像位于for循环中。控制台将在每个数字之后打印“完成”。
If the tab width is 3, then the print statement looks out of place. In this case, line 5 doesn’t match up with any indentation level. 如果制表符宽度为3,则打印语句看起来不合适。在这种情况下,第5行与任何缩进级别都不匹配。
When you run the code, you’ll get the following error and traceback: 运行代码时,您将收到以下错误和回溯信息:

$ python indentation.py
File "indentation.py", line 5
print('done')
^
TabError: inconsistent use of tabs and spaces in indentation

Notice the TabError instead of the usual SyntaxError. Python points out the problem line and gives you a helpful error message. It tells you clearly that there’s a mixture of tabs and spaces used for indentation in the same file. 注意TabError,而不是通常的SyntaxError。 Python指出了问题所在,并为您提供了有用的错误消息。它清楚地告诉您,同一文件中用于缩进的制表符和空格混合在一起。

The solution to this is to make all lines in the same Python code file use either tabs or spaces, but not both. For the code blocks above, the fix would be to remove the tab and replace it with 4 spaces, which will print 'done' after the for loop has finished. 解决方案是使同一Python代码文件中的所有行都使用制表符或空格,但不能同时使用两者。对于上面的代码块,解决方法是删除选项卡,并用4个空格替换它,在for循环完成后将打印“完成”。

Defining and Calling Functions 定义和调用函数

You might run into invalid syntax in Python when you’re defining or calling functions. For example, you’ll see a SyntaxError if you use a semicolon instead of a colon at the end of a function definition: 定义或调用函数时,Python可能会遇到无效的语法。例如,如果在函数定义的末尾使用分号而不是冒号,则会看到SyntaxError:

>>> def fun();
File "<stdin>", line 1
def fun();
^
SyntaxError: invalid syntax

The traceback here is very helpful, with the caret pointing right to the problem character. You can clear up this invalid syntax in Python by switching out the semicolon for a colon. 此处的回溯非常有帮助,插入符号指向问题字符。您可以通过用冒号代替分号来清除Python中的无效语法。

In addition, keyword arguments in both function definitions and function calls need to be in the right order. Keyword arguments always come after positional arguments. Failure to use this ordering will lead to a SyntaxError: 另外,函数定义和函数调用中的关键字参数都必须以正确的顺序排列。关键字参数始终位于位置参数之后。未能使用此排序将导致SyntaxError:

>>> def fun(a, b):
... print(a, b)
...
>>> fun(a=1, 2)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument

Here, once again, the error message is very helpful in telling you exactly what is wrong with the line. 在这里,错误消息再次非常有用,它可以告诉您确切的问题所在。

Changing Python Versions 更改Python版本

Sometimes, code that works perfectly fine in one version of Python breaks in a newer version. This is due to official changes in language syntax. The most well-known example of this is the print statement, which went from a keyword in Python 2 to a built-in function in Python 3: 有时,在一个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')?

This is one of the examples where the error message provided with the SyntaxError shines! Not only does it tell you that you’re missing parenthesis in the print call, but it also provides the correct code to help you fix the statement. 这是SyntaxError随附的错误消息发光的示例之一!它不仅告诉您在打印调用中缺少括号,而且还提供了正确的代码来帮助您修复该语句。

Another problem you might encounter is when you’re reading or learning about syntax that’s valid syntax in a newer version of Python, but isn’t valid in the version you’re writing in. An example of this is the f-string syntax, which doesn’t exist in Python versions before 3.6: 您可能会遇到的另一个问题是,当您正在阅读或学习语法时,该语法在Python的较新版本中是有效的语法,但在您编写的版本中无效。例如,f字符串语法,在3.6之前的Python版本中不存在:

>>> # 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

In versions of Python before 3.6, the interpreter doesn’t know anything about the f-string syntax and will just provide a generic "invalid syntax" message. The problem, in this case, is that the code looks perfectly fine, but it was run with an older version of Python. When in doubt, double-check which version of Python you’re running! 在3.6之前的Python版本中,解释器对f字符串语法一无所知,只会提供通用的“无效语法”消息。在这种情况下,问题在于代码看起来很好,但是它是在旧版本的Python上运行的。如有疑问,请仔细检查您正在运行的Python版本!

Python syntax is continuing to evolve, and there are some cool new features introduced in Python 3.8: Python语法在不断发展,Python 3.8中引入了一些很酷的新功能:

Walrus operator (assignment expressions) 海象运算符(赋值表达式)
F-string syntax for debugging 用于调试的F字符串语法
Positional-only arguments 仅位置参数
If you want to try out some of these new features, then you need to make sure you’re working in a Python 3.8 environment. Otherwise, you’ll get a SyntaxError. 如果您想尝试其中的一些新功能,则需要确保您正在Python 3.8环境中工作。否则,您将收到SyntaxError。

Python 3.8 also provides the new SyntaxWarning. You’ll see this warning in situations where the syntax is valid but still looks suspicious. An example of this would be if you were missing a comma between two tuples in a list. This would be valid syntax in Python versions before 3.8, but the code would raise a TypeError because a tuple is not callable: Python 3.8还提供了新的SyntaxWarning。在语法有效但仍然看起来可疑的情况下,您会看到此警告。例如,如果您缺少列表中两个元组之间的逗号。这在3.8之前的Python版本中将是有效的语法,但是代码将引发TypeError,因为不可调用元组:

>>> [(1,2)(2,3)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable

This TypeError means that you can’t call a tuple like a function, which is what the Python interpreter thinks you’re doing. 这个TypeError表示您不能像函数一样调用元组,这就是Python解释器认为您正在做的事情。

In Python 3.8, this code still raises the TypeError, but now you’ll also see a SyntaxWarning that indicates how you can go about fixing the problem: 在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

The helpful message accompanying the new SyntaxWarning even provides a hint ("perhaps you missed a comma?") to point you in the right direction! 新的SyntaxWarning附带的有用消息甚至提供了提示(“也许您错过了逗号?”),以向您指明正确的方向!

Conclusion 结论

In this tutorial, you’ve seen what information the SyntaxError traceback gives you. You’ve also seen many common examples of invalid syntax in Python and what the solutions are to those problems. Not only will this speed up your workflow, but it will also make you a more helpful code reviewer! 在本教程中,您已经了解了SyntaxError追溯向您提供了哪些信息。您还看到了Python中无效语法的许多常见示例,以及这些问题的解决方案。这不仅可以加快您的工作流程,而且还可以使您成为更有用的代码审阅者!

When you’re writing code, try to use an IDE that understands Python syntax and provides feedback. If you put many of the invalid Python code examples from this tutorial into a good IDE, then they should highlight the problem lines before you even get to execute your code. 在编写代码时,请尝试使用能够理解Python语法并提供反馈的IDE。如果您将本教程中的许多无效的Python代码示例放入一个好的IDE中,那么它们甚至应该在执行代码之前就突出显示问题所在。

Getting a SyntaxError while you’re learning Python can be frustrating, but now you know how to understand traceback messages and what forms of invalid syntax in Python you might come up against. The next time you get a SyntaxError, you’ll be better equipped to fix the problem quickly! 在学习Python时遇到SyntaxError可能令人沮丧,但是现在您知道了如何理解回溯消息以及您可能会遇到的Python形式的无效语法。下次收到SyntaxError时,您将可以更好地解决该问题!

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内