in

Python的常见语法错误及其修复方法

Python的常见语法错误及其修复方法

无论你是资深的Python程序员,还是刚刚开始学习Python,你可能都遇到过语法错误的问题。一个小小的标点符号遗漏就能导致代码崩溃,而错误信息有时并不会提供足够的线索。

通过阅读本文,你可以通过实际示例来学习如何理解、避免和修复Python语法错误。


什么是Python中的语法错误?

语法错误是代码中不符合语法规则的部分。换句话说,当Python解释器无法识别代码中的语句结构时,就会发生语法错误。

每种语言都有自己的规则来确保内容的正确表达。我们不能省略某些单词或字母,因为这会改变其含义。编程语言也是如此,包括Python在内。你的代码必须遵循Python的语法规则,才能被正确理解和执行。

编程语言的作用是将人类语言翻译成机器语言。因此,代码的执行有特定的步骤。当你运行代码时,Python解释器会先将代码解析成更小的组件,然后将其翻译成字节码,最后执行它。

在解析过程中,解释器会检查代码是否有语法错误。当发现第一个语法错误时,它会给出一个SyntaxError的消息。


如何阅读Python语法错误

当你收到错误消息时,Python会尝试指出错误的根本原因。有时候,消息会准确地告诉你问题所在,但有时它可能不太清楚甚至让人困惑。这是因为Python会标记它无法理解的第一个位置,因此错误可能显示在实际错误之后的代码行中。

学会如何阅读Python错误消息可以节省大量时间和精力。下面我们来看一个引发两个语法错误的Python网络抓取代码示例:

prices = {"price1": 9.99, "price2": 13.48 "price3": 10.99, "price4": 15.01}
price_found = False
for key value in prices.items():
    if 10 <= value <= 14.99:
        print(key + ":", value)
        price_found = True
if not price_found:
    print("There are no prices between $10 and $14.99")

在这个例子中,我们有一个包含不同价格的字典。我们使用for循环查找并打印 10 美元到 14.99 美元之间的价格。price_found变量使用布尔值来确定是否在字典中找到这样的价格。

执行时,Python 会指出它遇到的第一个无效语法错误,尽管过程中还有另外两个错误。第一个错误消息如下所示:

无效语法错误

黄色框中的信息可帮助我们确定错误的位置,绿色框包含有关错误本身的更多详细信息。完整消息可分为四个主要元素:

  1. 发生错误的文件的路径目录名称;

  2. 首次遇到错误的行号错误代码行;

  3. 插入符号 (^)指出错误的位置;

  4. 错误消息确定错误类型,后面跟着可能有助于解决问题的附加信息。

代码示例产生语法错误,该错误出现在代码的第一行——价格字典中。插入符号表示错误发生在“price2”:13.48“price3”:10.99之间,无效语法消息表示我们可能忘记在字典中的项目之间添加逗号。就是这样!Python 解释器建议了正确的解决方案,所以让我们更新代码:

prices = {"price1": 9.99, "price2": 13.48, "price3": 10.99, "price4": 15.01}

现在,重新运行代码以查看第二个语法错误是什么:

第二个语法错误

这次,插入符号无法准确指出错误的位置,并且SyntaxError消息不包含有关可能解决方案的其他信息。在这种情况下,经验法则是检查插入符号之前的代码。在代码示例中,出现语法错误是因为for循环中的变量keyvalue之间缺少逗号。语法正确的代码行应如下所示:

for key, value in prices.items():

当谈到 Python 语法错误的原因时,有时没有足够的信息让您走上正确的轨道。例如上面的无效语法错误示例。因此,了解导致 Python 语法错误的一些常见原因有助于轻松解决它们。


语法错误的常见原因

通常,常见的 Python 语法错误是由代码中的这些无效性引起的:

  • 标点符号放错位置、缺失或不匹配(括号、方括号、大括号、引号、逗号、冒号等);

  • 拼写错误、放错位置或缺失的 Python 关键字;

  • 变量名中有非法字符;

  • 缩进不正确;

  • 赋值运算符(=)使用不正确。

缺乏 Python 经验、复制粘贴错误和排版错误在这里起着重要作用。尤其是后者,因为排版错误很容易犯,而且很难发现,所以在生产过程中仔细检查代码是一种很好的做法。

无论如何,您可以在编码时采取其他步骤来减少出现语法错误的可能性。

如何避免 Python 语法错误?

  1. 使用集成开发环境 (IDE) 或代码编辑器,突出显示保留的 Python 关键字和错误,并在编写代码时建议修改。这是改进代码并避免 Python 中无效语法错误的首要步骤。

  2. 在编写代码时经常测试代码。这有助于从一开始就发现语法错误,并最大限度地降低以后重复犯同样错误的风险。

  3. 使用一致的缩进。不正确的缩进是 Python 中语法错误的常见原因之一,可以通过有意识地检查代码并使用突出显示缩进错误的 IDE 或代码编辑器来避免这种情况。

  4. 使用 linting 和 formatting 模块检查代码中的错误和样式。有些模块可以自动修复代码,节省您的时间和精力。当您只想在终端中运行 Python 而不需要 IDE 或代码编辑器时,linters 和 formatters 非常有用。一些值得一提的模块包括pycodestylepylintpyflakesFlake8Black

  5. 阅读 Python 文档。这确实是一个显而易见的建议,但Python 官方文档提供了许多有用的信息,不仅可以加深你的知识,还可以帮助您理解 Python 的语法和语法错误消息的含义。

请记住,这些步骤可以帮助您避免常见的 Python 语法错误,但不能消除它们。

即使您的代码在语法上是正确的,但代码运行时出现问题,也会出现异常。Python 运行时错误发生在代码执行期间,并会改变程序的正常流程。与语法错误(错误发生后会终止程序)不同,如果使用适当的异常处理程序,运行时错误可以继续运行程序。

此外,当代码在语法上有效且运行时没有错误,但输出却不是预期时,就会发生逻辑错误。虽然本文探讨了无效语法问题,但应该注意的是,SyntaxError 异常更广泛的异常组的一部分。对于高级 Python 编程,建议了解其他错误及其处理方法。


如何修复语法错误

现在我们已经讨论了 Python 语法错误的常见原因以及避免这些错误的一般技巧,让我们看一些实际的代码示例并修复它们。

标点符号放错位置、缺失或不匹配

1. 确保圆括号()、方括号[]

list_of_URLs = (
    'https://example.com/1',
    'https://example.com/2",
    'https://example.com/3
)
print(list_of_URLs)

# Error message
  File "<stdin>", line 3
    'https://example.com/2",
    ^
SyntaxError: unterminated string literal (detected at line 3)

 

和大括号{}正确闭合。如果不闭合,Python 解释器会将第一个圆括号、方括号或大括号后面的所有内容视为单个语句。请查看此网页抓取代码示例,该示例向我们的网页爬虫工具发送一组抓取指令:

payload = {
    "url": "https://www.example.com/",
    "filters": {
        "crawl": [".*"],
        "process": [".*"],
        "max_depth": 1,
    "scrape_params": {
        "user_agent_type": "desktop",
    },
    "output": {
        "type_": "sitemap"
    }
}

# Error message
  File "<stdin>", line 1
    payload = {
              ^
SyntaxError: '{' was never closed

乍一看,似乎这个数据包已经用大括号闭合了,但Python解释器却抛出一个语法错误,表明情况并非如此。在这个特定的例子中,“filters”参数没有用大括号闭合,而解释器在回溯信息中并没有显示这一点。你可以通过闭合“filters”参数来修复这个错误:

payload = {
    "url": "https://www.amazon.com/",
    "filters": {
        "crawl": [".*"],
        "process": [".*"],
        "max_depth": 1
    }, # Add the missing brace
    "scrape_params": {
        "user_agent_type": "desktop",
    },
    "output": {
        "type_": "sitemap"
    }
}

2. 确保使用正确的引号结束字符串。例如,如果您的字符串以单引号 ‘ 开头,则请在字符串末尾再次使用单引号。以下代码片段说明了这一点:

list_of_URLs = (
    'https://example.com/1',
    'https://example.com/2",
    'https://example.com/3
)
print(list_of_URLs)

# Error message
  File "<stdin>", line 3
    'https://example.com/2",
    ^
SyntaxError: unterminated string literal (detected at line 3)

这个例子中有两个错误,但正如你所见,解释器只显示了第一个语法错误。它准确地指出了问题所在,即字符串以单引号开始,却以双引号结束。

第二个错误在第三个示例URL中,该URL根本没有用引号闭合。语法正确的版本应该是这样的:

list_of_URLs = (
    'https://example.com/1',
    'https://example.com/2',
    'https://example.com/3'
)
print(list_of_URLs)

当字符串内容本身包含引号时,请使用单引号、双引号和/或三引号”'来指定字符串的开始和结束位置。例如:

print("In this example, there's a "quote within 'a quote'", which we separate with double and single quotes.")

# Error message
  File "<stdin>", line 1
    print("In this example, there's a "quote within 'a quote'", which we separate with double and single quotes.")
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?

解释器显示了错误发生的位置,你可以看到插入符号在第二个双引号内结束。要修复这个语法错误,你可以用三引号(”' 或 “””)将整个字符串括起来:

print("""In this example, there's a "quote within 'a quote'", which we specify with double and single quotes.""")

3. 传递多个参数或值时,请务必使用逗号分隔它们。请考虑以下将 HTTP 标头封装在 headers 字典中的 Web 抓取示例:

headers = {
    'Accept': 'text/html',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US, en;q=0.9'
    'Connection': 'keep-alive'
}

# Error message
  File "<stdin>", line 5
    'Connection': 'keep-alive'
                ^
SyntaxError: invalid syntax

同样,解释器没有准确显示问题所在,但通常你可以预期实际的语法错误发生在插入符号指向的位置之前。你可以通过在‘Accept-Language’参数后添加缺失的逗号来修复这个错误:

headers = {
    'Accept': 'text/html',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US, en;q=0.9',
    'Connection': 'keep-alive'
}

4. 不要忘记在函数或复合语句(如 if、for、while、def 等)的末尾添加一个冒号 :。让我们看一个网络抓取的例子:

def extract_product_data()
    for url in product_urls
        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.content, 'html.parser')
        title = soup.find("h1").text
        price = soup.find("span", {"itemprop": "price"}).text
        product_data.append({
            "title": title,
            "price": price,
        })

# Error message
File "<stdin>", line 1
    def extract_product_data()
                              ^
SyntaxError: expected ':'

这次,解释器显示了发生错误的确切位置,并提示了可以采取哪些措施来解决问题。在上面的例子中,def函数和for循环缺少冒号,因此我们可以更新代码:

def extract_product_data():
    for url in product_urls:

拼写错误、放错位置或缺失 Python 关键字

1. 确保你没有使用保留的 Python 关键字来命名变量和函数。如果你不确定某个单词是否是 Python 关键字,请使用Python 中的关键字模块检查它,或在保留关键字列表中查找它。许多 IDE(如 PyCharm 和 VS Code)都会突出显示保留关键字,这非常有用。下面的代码片段使用保留关键字pass来保存密码值,这会导致语法错误消息:

user = 'username1'
pass = 'password1'

# Error message
  File "<stdin>", line 2
    pass = 'password1'
         ^
SyntaxError: invalid syntax

2. 确保你没有拼错 Python 关键字。例如:

import time
from requests impotr Session

# Error message
  File "<stdin>", line 2
    from requests impotr Session
                  ^^^^^^
SyntaxError: invalid syntax

此代码示例尝试从请求库导入Session对象。但是,Python 关键字import拼写错误为impotr,从而引发了无效语法错误。

3. 将 Python 关键字放在不该出现的位置也会引起错误。确保 Python 关键字的语法顺序正确,并遵循该关键字的特定规则。请考虑以下示例:

import time
import Session from requests

# Error message
  File "<stdin>", line 2
    import Session from requests
                   ^^^^
SyntaxError: invalid syntax

这里,我们看到一个无效语法错误,因为 Python 关键字from不遵循正确的语法顺序。修复后的代码应如下所示:

import time
from requests import Session

变量名称中的非法字符

Python 变量必须遵循一定的命名约定:

1. 变量名不能使用空格。最好的解决方案是使用下划线字符。例如,如果你想要一个名为“two words”的变量,它应该写成two_wordstwowordsTwoWordstwoWordsTwowords

2. 变量区分大小写。这意味着example1Example1是两个不同的变量。在创建变量并在代码中调用它们时,请考虑到这一点。

3. 不要用数字开头变量。Python 会给出语法错误:

response1 = requests.get(url)
2response = requests.post(url)

# Error message
  File "<stdin>", line 2
    2response = requests.post(url)
    ^
SyntaxError: invalid decimal literal

正如你所见,解释器允许在变量名中使用数字,但变量名不能以数字开头。

4. 变量名只能使用字母、数字和下划线。变量名中使用任何其他字符都会产生语法错误。


缩进错误

1. 请记住,某些Python命令(如复合语句和函数)需要通过缩进来定义命令的范围。因此,确保代码中的此类命令正确缩进。例如:

prices = (16.99, 13.68, 24.98, 14.99)


def print_price():
    for price in prices:
    if price < 15:
        print(price)

print_price()


# Error message 1
  File "<stdin>",line 6
    if price < 15:
    ^
IndentationError: expected an indented block after 'for' statement on line 5


# Error message 2
  File "<stdin>", line 7
    print(price)
    ^
IndentationError: expected an indented block after 'if' statement on line 6

第一条错误消息表明if语句需要缩进块。修复该问题并运行代码后,我们遇到第二条错误消息,该消息告诉我们print语句超出了if语句的范围,需要再次缩进。使用正确的缩进修复代码:

prices = (16.99, 13.68, 24.98, 14.99)


def print_price():
    for price in prices:
        if price < 15:
            print(price)

print_price()

2. 使用一致的缩进标记:全部使用空格或全部使用制表符。不要混淆它们,因为这会降低代码的可读性,从而使得仅通过查看代码就很难找到错误的缩进。大多数 Python IDE 会在运行代码之前突出显示缩进错误,因此您可以自动重新格式化文件以修复缩进。

让我们采用上面的代码示例,并通过在if语句前添加一个空格来修复第一个错误消息:

prices = (16.99, 13.68, 24.98, 14.99)


def print_price():
    for price in prices:
     if price < 15:
        print(price)

print_price()

代码运行正常,没有错误,并打印出正确的结果。但是,您可以看到空格和制表符的混合使代码更难阅读。使用这种方法可能会带来不必要的语法错误,而这些错误可以通过在整个代码中坚持使用空格或制表符来避免。


赋值运算符 (=) 使用不正确

1. 确保不要使用赋值运算符=为函数或文字赋值。您只能为变量赋值。以下是一些示例的概述:

"price" = 10.98

# Error message
  File "<stdin>", line 1
    "price" = 10.98
    ^^^^^^^
SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?

字符串“price”不能充当变量,因此必须删除引号:

price = 10.98

在下面的例子中,我们要检查值10.98是否是浮点类型:

price = 10.98
type(price) = float

# Error message
  File "<stdin>", line 2
    type(price) = float
    ^^^^^^^^^^^
SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='

Python解释器会抛出一个错误,因为赋值运算符不能用于将值赋给一个函数。正确的方法是使用以下代码示例之一:

price = 10.98
print(type(price))

# or

price = 10.98
is_float = type(price) == float
print(is_float)

2. 使用冒号: 而不是赋值运算符=为字典赋值。让我们采用之前的代码示例并对其进行修改,使其错误地使用赋值运算符而不是冒号:

headers = {
    'Accept' = 'text/html',
    'Accept-Encoding' = 'gzip, deflate, br',
    'Accept-Language' = 'en-US, en;q=0.9',
    'Connection' = 'keep-alive'
}


# Error message
  File "<stdin>", line 2
    'Accept' = 'text/html',
    ^^^^^^^^
SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?

3. 根据对象的值进行比较时使用==。例如:

price_1 = 200.99
price_2 = 200.98

compare = (price_1 = price_2)
print(compare)

# Error message
  File "<stdin>", line 4
    compare = (price_1 = price_2)
               ^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?

你可以通过在price_1price_2之间使用双等号==而不是=来解决该问题,这将打印正确的结果。


总    结

Python中的语法错误有时很难解决,这取决于具体的错误类型。不过,当你了解错误回溯的工作原理,知道这些错误的常见原因和解决方法后,就可以大大减少调试所需的时间和精力。希望这篇文章能帮助你走上正确的道路,开始编写没有语法错误的Python代码。

Written by 河小马

河小马是一位杰出的数字营销行业领袖,广告中国论坛的重要成员,其专业技能涵盖了PPC广告、域名停放、网站开发、联盟营销以及跨境电商咨询等多个领域。作为一位资深程序开发者,他不仅具备强大的技术能力,而且在出海网络营销方面拥有超过13年的经验。