Python中通常不做严格的类型定义,但如果是常用且固定的数据结构,还是定义清楚使用起来更方便(起码对象后面打.的时候,IDE可以自动给出方法和属性名提示)。这时,一个复杂的结构,就有可能循环引用,比如:

from typing import List


class A:
    x: str
    y: B


class B:
    w: List[A]

这样的代码,连编译都过不去,会在‘y: B’,这个位置,直接提示:‘Unresolved reference B’。解决方案有两个:

  1. 保持在同一个文件中定义类
    此时可以添加一个特殊的引用:from __future__ import annotations,告知编译器先“通读”整个文件,再处理typing annotation,就可以避免上述问题。
  2. 拆分到不同模块中
    这种情况下,就得在引用另外一个类的时候,直接引用它的模块,而不是类名:
from . import Module2


class A:
    x: str
    y: Module2.B
from typing import List

from . import Module1


class B:
    w: List[Module1.A]

2021-11-17 更新

  1. 调整import顺序
    在python代码中,import顺序是有影响的,比如我的一个项目中,某几个类是这样的:

    from simplerpa.core.data.Action import Action
    from simplerpa.core.action.ActionScreen import ActionScreen
    
    class Executor:
     pass
    
    ...
    
    from simplerpa.core.action.ActionData import ActionData
    from simplerpa.core.action.ActionImage import ActionImage
    from simplerpa.core.action.ActionKeyboard import ActionKeyboard
    from simplerpa.core.action.ActionScreen import ActionScreen
    
    class Action:
     pass
    
    ...
    
    from simplerpa.core.action.ActionImage import ActionImage
    class ActionScreen:
     pass

之前Excecutor的import,Action在ActionScreen的后面,死活提示"无法import ActionImage",对调顺序以后就好了。然而诡异的是,自从调整完毕,现在调回去也不出错了。。。我仔细查看了当时调整的git日志,就算完全退回当时的状态,也不出错(悲伤...)。

无论如何,调整顺序也是值得尝试的一个方法。而且pycharm有个坑,它的“Optimize Imports”功能,不仅仅会删除没用的import,还会自动调整import顺序,有可能优化以后,代码就跑不了了。

03-05 20:19