gpt4 book ai didi

python - 跨文件循环依赖的类型提示

转载 作者:行者123 更新时间:2023-12-01 09:06:41 25 4
gpt4 key购买 nike

假设你有这样的东西:

class Point:
def compute_line(self, point: 'Point') -> 'Line':
# computes line connecting self to point
...


class Line:
def compute_intersection(self, line: 'Line') -> 'Point':
# computes point formed from intersection of self and line
...

PyCharm 可以解析 str 键入提示以自动完成任一方法的输出。

但是如果我想将 PointLine 放在单独的文件中怎么办?有什么办法仍然可以自动完成吗?

最佳答案

问题是 Line 根本不是 point.py 中类型的名称,而 Point 也不是line.py 中类型的名称。将其放在引号中没有帮助;这只是延迟了字符串的解析。它仍然必须最终解析为一种类型,因此您只是将事情延迟到它们解析为 NameError 的程度,这没有帮助。

如果您在Point中执行导入线并在Line中执行导入点,则点.Pointline.Line 成为类型,解决了这个问题。但当然它会产生一个新问题:循环导入。

<小时/>

在某些情况下,as explained in PEP 484 ,您可以通过执行有条件的“仅静态输入”导入来解决该问题,如下所示:

import typing
if typing.TYPE_CHECKING:
import line

…然后在类型注释中使用'line.Line'

请参阅 TYPE_CHECKING 上的文档更多细节。 (特别是,如果您需要与 3.5.2 之前的 Python 3.5 兼容,这将在运行时给您一个 NameError 而不是 False,这是一个痛苦......但不是很多人们需要在 3.5.1 上运行。)

<小时/>

如果这不能解决问题,您需要一些方案来避免循环导入,就像运行时循环导入一样。

例如,您可以采用传统的“接口(interface)”解决方案,其中第一个类型依赖于第二个类型,但第二个类型不依赖于第一个,它仅依赖于第一个类型的父类(super class)。

通常,这个父类(super class)是一个 ABC,表明它仅作为其他地方定义的某个实际类的接口(interface)。 (这样,Python 和静态检查器就可以强制执行,任何类型为 ABC 的内容都必须是该 ABC 的具体子类之一的实例,而该子类只有一个。)

# pointbase.py
import abc
class PointBase(abc.ABC):
@abc.abstractmethod
def method_that_does_not_need_line(self):
pass

# point.py
import pointbase
import line
class Point(pointbase.PointBase):
def method_that_does_not_need_line(self):
do_stuff()
def method_that_does_need_line(self, line: line.Line):
do_stuff(line)

# line.py
import pointbase
class Line:
def method_that_needs_point(self, point: pointbase.PointBase):
do_stuff(point)

关于python - 跨文件循环依赖的类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51989813/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com