假设我们有这样的函数定义:
def f(*, model: Optional[Type[pydantic.BaseModel]] = None)
因此,该函数不需要安装pydantic
,直到您将某个内容作为model
传递。现在假设我们想将函数打包到pypi包中。我的问题是,是否有一种方法可以避免仅仅为了类型检查而将pydantic
引入包依赖关系?
我试图听从dsenser的建议,但我发现我的py仍然给我Name 'pydantic' is not defined
错误。然后我在文档中找到了这一章,它似乎也适用于我的情况:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import pydantic
您可以将普通类(而不是字符串文字(与__future__.annotations
(python 3.8.1(一起使用:
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Type
if TYPE_CHECKING:
import pydantic
def f(*, model: Optional[Type[pydantic.BaseModel]] = None):
pass
如果由于某种原因您不能使用__future__.annotations
,例如您在python<3.7,使用dsenser解决方案中的字符串文字进行键入。
Python的typing
模块可以使用字符串类型名称以及类型本身,正如您在示例中所使用的那样。
如果您不希望在运行代码时计算类型,并且在未导入模块时引发异常,那么您可能更喜欢使用字符串名称。您的代码片段将是:
def f(*, model: Optional[Type["pydantic.BaseModel"]] = None)
使用mypy
的静态类型检查应该可以继续工作,但您的包将不再总是需要依赖pydantic
。
正如您在文档中所发现的,python的typing
模块包括一种指定某些导入仅用于(字符串文字(类型注释的方法:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import pydantic
仅当TYPE_CHECKING
为True
时,这将执行import pydantic
语句,主要是在使用mypy
分析代码中的类型时。正常运行程序时,不执行import语句。因此,该选项只能与字符串文字类型提示一起使用;否则,缺少导入将导致程序的正常执行失败。
由于类型提示的惰性评估将在Python 4.0中实现,
from __future__ import annotations
可以用于在Python 3中启用此行为。使用此import语句,不需要字符串文字类型。
我会做一些类似的事情
try:
from pydantic import BaseModel as PydanticBaseModel
except ImportError:
PydanticBaseModel = None
我不认为这比dspencer提出的要好,但有时一些奇怪的样式指南可能会禁止您使用字符串类型名称,所以我只想指出另一个解决方案。