如何使用 pydantic 创建链接列表以便自动完成不会中断

How to create linked lists using pydantic so auto-completion doesn't break

我正在尝试使用 pydantic 创建链表。

以下代码可以工作,但我无法让自动完成工作。从随附的屏幕截图中可以看出,属性 'next' 不显示自动完成。

如何保留自动排版

更新:我正在开发 Pycharm Professional 2020.3 + Python 3.10.2 + pydantic 1.9.0


代码

from pydantic import BaseModel
from pydantic.typing import ForwardRef

Node = ForwardRef('Node')


class Node(BaseModel):
    data: int
    next: Node = None


# Node.update_forward_refs()

def get_l1() -> Node:
    l1: Node = Node(data=1)
    l1.next = Node(data=2)
    l1.next.next = Node(data=3)

    return l1


l2: Node = get_l1()

print(l2)
print(l2.next)
print(l2.next.next)

输出

data=1 next=Node(data=2, next=Node(data=3, next=None))
data=2 next=Node(data=3, next=None)
data=3 next=None

截图

不要使用 ForwardRef,请使用 typing.Optional,因为您将 None 分配给 node 字段并用引号将 Node 括起来:

# Node = ForwardRef('Node')  <- Do not use this


class Node(BaseModel):
    data: int
    next: Optional["Node"] = None # <- Use typing.Optional and quotes here

关于 typing.Optional 来自 pydantic documentation:

typing.Optional

Optional[x] is simply short hand for Union[x, None];

根据PEP 484

关于前向引用类型提示中引号的使用

When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.

A situation where this occurs commonly is the definition of a container class, where the class being defined occurs in the signature of some of the methods. For example, the following code (the start of a simple binary tree implementation) does not work:

class Tree:
    def __init__(self, left: Tree, right: Tree):
        self.left = left
        self.right = right

To address this, we write:

class Tree:
    def __init__(self, left: 'Tree', right: 'Tree'):
        self.left = left
        self.right = right