Python 的type hint和循环引用

# Python 的type hint和循环引用


这两天拿 Python 在写电梯应用的多线程程序,碰到了这样的问题,我用 flask-socketio + HTML 做用户界面,这里碰到一个循环引用的问题:


1. *main.py*


```python
...
from LiftUtils.LiftController import LiftController


app = Flask(__name__)
bootstrap = Bootstrap(app)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
...
```


1. *LiftUtils.LiftController*


```python
from typing import Tuple


from LiftUtils.Job import Job
from LiftUtils.Lift import Lift




class LiftController:
    def __init__(self, socketio=None):


        self._socket = socketio
        self._lifts: Tuple[Lift] = tuple(Lift(i, self) for i in range(1, 6))
        # 剩余工作的队列,对于到来的工作用FIFO
        self._remained_jobs: Queue = Queue()
        # 开启任务
        self._start_deamon()
```


1. *LiftUtils.Lift*


```python
from LiftUtils.LiftState import LiftState
from LiftUtils.LiftController import LiftController
from LiftUtils.Job import Job




class Lift:
    FLOOR_STEP_TIME = 1
    _class_lock: Lock = Lock()
    lift_objects: List[Job] = []
```


以上代码出现了如下的错误:


```
Traceback (most recent call last):
  File "/Users/fuasahi/OperatingSystem/LiftMetric/main.py", line 10, in
    from LiftUtils.LiftController import LiftController
  File "/Users/fuasahi/OperatingSystem/LiftMetric/LiftUtils/LiftController.py", line 12, in
    from LiftUtils.Lift import Lift
  File "/Users/fuasahi/OperatingSystem/LiftMetric/LiftUtils/Lift.py", line 7, in
    from LiftUtils.LiftController import LiftController
ImportError: cannot import name 'LiftController'
```


实际上,这是一个循环引用的问题,一开始看了hubo大大的知乎,https://www.zhihu.com/question/19887316       


我还以为自己跟往常一样脑残了...不过后来发现这个实际上是因为我这里强行type hint,自然搞出了问题,汗颜...


这边先可以了解下type hint: https://stackoverflow.com/questions/39971929/what-are-variable-annotations-in-python-3-6/39973133#39973133


这里采用以下的方法


```python
if TYPE_CHECKING:
    from LiftUtils.LiftController import LiftController
    from LiftUtils.Job import Job




class Lift:
    FLOOR_STEP_TIME = 1
    _class_lock: 'Lock' = Lock()
    lift_objects: 'List[Job]' = []
```


专门用于type hint的时候,更多标记成字符串标注类型。这里使用了类似C++的前向引用,不过感觉...我这里导入都跟“类型都要 if TYPE_CHECKING”一样,莫名其妙感觉很别扭 ...有大佬知道什么好方法可以短信我...


## 参考


https://stackoverflow.com/questions/32557920/what-are-type-hints-in-python-3-5


https://stackoverflow.com/questions/39740632/python-type-hinting-without-cyclic-imports


https://docs.python.org/3/library/typing.html


##  补充


参考了 https://stackoverflow.com/questions/36286894/name-not-defined-in-type-annotation 。好像 Python 3.7 解决了这个问题... 汗颜,刚刚还在朋友圈黑了一句...


不管怎么样,希望 Python 越来越好…希望我越来越强...

你可能感兴趣的:(Python 的type hint和循环引用)