Python 3.10 类型提示导致语法错误

Python 3.10 Type Hinting causes Syntax Error

我定义了两个class。一个 Bookshelf class 和一个 Book class 并且每个都定义了自己的方法和类型提示。当我使用 python 3.10 运行 VS Code 中的以下代码时,出现以下错误:

class Bookshelf: 
SyntaxError: Invalid syntax

指的是下面BookShelfclass的init。你们中有人能发现问题吗?

class Bookshelf:

    def __init__(self, books: list[Book]):
        self.books = books

    def __str__(self) -> str:
        return f"Bookshelf with {len(self.books)}"


class Book:
    def __init__(self, name: str, page_count: int):
        self.name=name
        self.page_count = page_count

尝试切换:

list[Book]

与:

'list[Book]'

使用您问题中的代码,我实际上得到了 NameError,因为 Book 在定义之前用于类型提示。将 Book class 移动到 Bookshelf 上方即可。

class Book:
    def __init__(self, name: str, page_count: int):
        self.name = name
        self.page_count = page_count


class Bookshelf:
    def __init__(self, books: list[Book]):
        self.books = books

    def __str__(self) -> str:
        return f"Bookshelf with {len(self.books)} books."

atlas = Book("Atlas", 100)
dictionary = Book("Dictionary", 1000)
print(atlas)
print(Bookshelf([atlas, dictionary]))

输出:

<__main__.Book object at 0x7f61af441fd0>
Bookshelf with 2 books.

它不是 SyntaxError,而是 NameError,因为当您在类型提示中使用它时 Book class 尚未定义。

1.第一个解决方案 是将 Book class 的定义移动到 BookShelf.

之前

2。第二个解决方案 是使用字符串而不是 book 本身:

def __init__(self, books: list["Book"]):

我认为在 Python 3.11 中,他们将允许按原样使用它。类型注释的评估将被推迟:

https://peps.python.org/pep-0563/

3。第三种解决方案:如果你现在想拥有这个,你可以导入:

from __future__ import annotations

那么你的代码就可以工作了。

  1. 您在 books: list[Book]
  2. 中引用后定义了 Book class
  3. 您不能使用 list[Book] 作为参数,因为类型 list 已经在 Python
  4. 中定义

试试这个:

from typing import List #Using typing's List instead of list

class Book:
    def __init__(self, name: str, page_count: int):
        self.name=name
        self.page_count = page_count
#Defined book class before its use
        
list_of_books = List[Book] #Using a type alias to solve the problem so you can use it as a parameter

class Bookshelf:

    def __init__(self, books: list_of_books):
        self.books = books

    def __str__(self) -> str:
        return f"Bookshelf with {len(self.books)}"

使用type aliases定义您想要的复杂参数类型。 参见