Python Typing:Self-Referencing Models

问题描述

在开发过程中,可能遇到如下情况:

from pydantic import BaseModel

class Foo(BaseModel):
    a: int = 123
    b: Foo = None

Foo 的属性 b 类型是 Foo,存在这种自我引用的状态,但是直接这么写会报错。

解决办法

方式一:ForwardRef [Python 3.8+]

from typing import ForwardRef
from pydantic import BaseModel

Foo = ForwardRef('Foo')


class Foo(BaseModel):
    a: int = 123
    b: Foo = None


Foo.update_forward_refs()

方式二:使用字符串定义

from pydantic import BaseModel


class Foo(BaseModel):
    a: int = 123
    #: The sibling of `Foo` is referenced by string
    sibling: 'Foo' = None


Foo.update_forward_refs()

【推荐】方式三:导入 annotations

from __future__ import annotations
from pydantic import BaseModel


class Foo(BaseModel):
    a: int = 123
    #: The sibling of `Foo` is referenced directly by type
    sibling: Foo = None


Foo.update_forward_refs()
  • Python 3.7 必须将 from __future__ import annotations 写在首行
  • Python 3.10+ 会默认使用这个特性

参考资料

推荐阅读更多精彩内容