当使用可选导入时,即将包仅作为我想要它成为我的软件包的可选依赖项而在函数内导入时,有没有一种方法可以将函数的返回类型标注为属于此可选依赖项之一的类呢?
以pandas
作为可选依赖项的简单示例:
def my_func() -> pd.DataFrame:
import pandas as pd
return pd.DataFrame()
df = my_func()
在这种情况下,由于import
语句位于my_func
内部,因此这段代码会不出所料地引发以下错误:如果改用字符串字面量类型提示,则如下所示:i.e.:NameError: name 'pd' is not defined
def my_func() -> 'pd.DataFrame':
import pandas as pd
return pd.DataFrame()
df = my_func()
现在可以执行该模块,但mypy
会抱怨:
错误:名称 'pd' 未定义
我如何使该模块成功执行并保留静态类型检查功能,同时又可以选择性地进行导入?
TYPE_CHECKING
。在这种情况下,由于未导入pandas
,代码将在运行时失败。这是否仍需要在my_func
中导入? - dspencerTYPE_CHECKING
替换了TYPE_HINTING
,并在第一个示例中添加了缺失的导入。 - Michael0x2aPANDAS_EXISTS = bool(importlib.util.find_spec('pandas'))
或更糟糕的PANDAS_EXISTS = not not importlib.util.find_spec('pandas')
,其中find_spec
返回importlib.machinery.ModuleSpec
或 None。当然,错误捕获看起来不太优雅,但完全符合PEP20(Python之禅)的指南,因为EAFP是其关键原则,另外使用importlib.util
不太容易理解(与PEP8、可读性相比),尤其是如果已经安装了pandas但由于缺少依赖项而无法导入它,则在导入时会引发 ImportError,但是find_spec
会毫不知情。 - Matteo Ferla