Python 包对象的转发引用
Python Forward References for Package Objects
我怀疑答案是肯定的,但我想问清楚。如果我有一个函数需要使用,例如,一个 numpy
对象,但我没有在我的模块中直接使用 numpy
,我可以使用前向引用来类型提示我的参数而不是导入numpy
直接?
换句话说(假设Python3.7+),我可以这样吗
# forward-reference.py
def my_func(arr: "np.ndarray") -> int:
# does some operations with arr
而不是这个
# direct-import.py
import numpy as np
def my_func(arr: np.ndarray) -> int:
# do some operations on arr...
我无法想象核心开发人员会要求程序员仅仅为了类型提示而导入一个模块。我的 pylint
或 flake8
linters 会正确地将那些作为未使用的模块挑选出来,我认为所有这些额外的导入都是多余的。
编辑
为了测试,我创建了两个文件:demo1.py
和 demo2.py
(都位于同一目录中):
demo1.py
# demo1.py
import numpy as np
from demo2 import my_func
if __name__ == "__main__":
a = np.array([1, 2, 3])
print(my_func(a))
demo2.py
# demo2.py
def my_func(arr: "np.ndarray") -> int:
return arr[0]
运行 mypy
on demo1.py
没有错误,但是 运行 on demo2.py
with either numpy.ndarray
给出错误:
demo2.py:1: error: Name "numpy" is not defined
或np.ndarray
给出错误:
demo2.py:1: error: Name "np" is not defined
所以如果我先设计一个模块 demo2.py
,在我设计 demo1.py
之前打算让它接受 numpy 数组,mypy
会出错。
是否有更好/“正确”的方法来处理上述情况?
不,你不能。
您需要将名称包含在范围内(毕竟,您本可以完成愚蠢的进口部并完成 import math as np
),但如果您不这样做,则可以使用 typing.TYPE_CHECKING
想要真正导入模块:
from typing import TYPE_CHECKING
if TYPE_CHECKING: # never true unless you're a type checker
import numpy as np
def my_func(arr: "np.ndarray") -> int:
pass # does some operations with arr
除此之外,类型检查器不(或不应该)关心你对事物的称呼;他们将以最佳能力解析符号,例如这应该有效:(但请不要...)
from typing import TYPE_CHECKING
if TYPE_CHECKING: # never true unless you're a type checker
import numpy as noooooooooop
bazoop = noooooooooop.ndarray
glerp = int
def my_func(arr: "bazoop") -> "glerp":
pass # does some operations with arr
我怀疑答案是肯定的,但我想问清楚。如果我有一个函数需要使用,例如,一个 numpy
对象,但我没有在我的模块中直接使用 numpy
,我可以使用前向引用来类型提示我的参数而不是导入numpy
直接?
换句话说(假设Python3.7+),我可以这样吗
# forward-reference.py
def my_func(arr: "np.ndarray") -> int:
# does some operations with arr
而不是这个
# direct-import.py
import numpy as np
def my_func(arr: np.ndarray) -> int:
# do some operations on arr...
我无法想象核心开发人员会要求程序员仅仅为了类型提示而导入一个模块。我的 pylint
或 flake8
linters 会正确地将那些作为未使用的模块挑选出来,我认为所有这些额外的导入都是多余的。
编辑
为了测试,我创建了两个文件:demo1.py
和 demo2.py
(都位于同一目录中):
demo1.py
# demo1.py
import numpy as np
from demo2 import my_func
if __name__ == "__main__":
a = np.array([1, 2, 3])
print(my_func(a))
demo2.py
# demo2.py
def my_func(arr: "np.ndarray") -> int:
return arr[0]
运行 mypy
on demo1.py
没有错误,但是 运行 on demo2.py
with either numpy.ndarray
给出错误:
demo2.py:1: error: Name "numpy" is not defined
或np.ndarray
给出错误:
demo2.py:1: error: Name "np" is not defined
所以如果我先设计一个模块 demo2.py
,在我设计 demo1.py
之前打算让它接受 numpy 数组,mypy
会出错。
是否有更好/“正确”的方法来处理上述情况?
不,你不能。
您需要将名称包含在范围内(毕竟,您本可以完成愚蠢的进口部并完成 import math as np
),但如果您不这样做,则可以使用 typing.TYPE_CHECKING
想要真正导入模块:
from typing import TYPE_CHECKING
if TYPE_CHECKING: # never true unless you're a type checker
import numpy as np
def my_func(arr: "np.ndarray") -> int:
pass # does some operations with arr
除此之外,类型检查器不(或不应该)关心你对事物的称呼;他们将以最佳能力解析符号,例如这应该有效:(但请不要...)
from typing import TYPE_CHECKING
if TYPE_CHECKING: # never true unless you're a type checker
import numpy as noooooooooop
bazoop = noooooooooop.ndarray
glerp = int
def my_func(arr: "bazoop") -> "glerp":
pass # does some operations with arr