代码之家  ›  专栏  ›  技术社区  ›  dshin

具有跨文件循环依赖关系的类型提示

  •  1
  • dshin  · 技术社区  · 8 年前

    假设你有这样的东西:

    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类型提示以自动完成任意方法的输出。

    Point 和 Line 在不同的文件里?还有什么办法可以自动完成吗?

    2 回复  |  直到 8 年前
        1
  •  1
  •   abarnert    8 年前

    问题是 Line 不是类型的名称 point.py Point 不是内部类型的名称 line.py NameError ,这没什么用。

    如果你做一个 import line 在里面 点 和 import point 生产线 ,然后 point.Point 和 line.Line


    在某些情况下, as explained in PEP 484 ,只需执行条件“static typing only”导入即可解决此问题,如下所示:

    import typing
    if typing.TYPE_CHECKING:
        import line
    

    然后使用 'line.Line' 在类型批注中。

    TYPE_CHECKING 更多细节。(特别是,如果您需要与3.5.2之前的Python3.5兼容,这将为您提供 命名错误 而不是 False


    例如,您可以使用传统的“接口”解决方案,其中第一个类型依赖于第二个,但第二个不依赖于第一个,它只依赖于第一个的超类。

    通常,这个超类将是一个ABC,表示它只是作为一个接口来服务于其他地方定义的一些真实类。(这样,你知道,Python和你的静态检查器可以强制执行,任何类型为ABC的东西都必须是ABC of的一个具体子类的实例,只有一个)

    # 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)
    
        2
  •  0
  •   Roei Yehuda    8 年前

    您可以有该类型的断言,PyCharm会将其识别为您断言的类型。

    assert isinstance(point, Point)