如何使用 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
我正在尝试使用 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 forUnion[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