Skip to content

Commit 983b3c2

Browse files
committed
TYPE_CHECKING_tutorial
1 parent 6edf39d commit 983b3c2

File tree

8 files changed

+124
-0
lines changed

8 files changed

+124
-0
lines changed

type-hints-tutorial/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ A compromise is possible where a __future__ import could enable turning all anno
103103

104104
- [Protocol](https://github.com/twtrubiks/python-notes/blob/master/type-hints-tutorial/Protocol_tutorial.py)
105105

106+
- [TYPE_CHECKING](https://github.com/twtrubiks/python-notes/tree/master/type-hints-tutorial/TYPE_CHECKING_tutorial) - 說明 TYPE_CHECKING 用法
107+
106108
### Type comments
107109

108110
```python
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# TYPE_CHECKING 介紹
2+
3+
說明一下 TYPE_CHECKING 的功能, 主要功能是避免 python 循環引用以及讓 IDE 支援靜態檢查.
4+
5+
```python
6+
from typing import TYPE_CHECKING
7+
```
8+
9+
先來看一個例子 [module_a.py](module_a.py)
10+
11+
```python
12+
from module_b import ClassB
13+
14+
class ClassA:
15+
def __init__(self, b: ClassB) -> None:
16+
self.b = b
17+
18+
def use_b(self) -> None:
19+
print("Using ClassB from ClassA")
20+
```
21+
22+
[module_b.py](module_b.py)
23+
24+
```python
25+
from module_a import ClassA
26+
27+
class ClassB:
28+
def __init__(self, a: ClassA) -> None:
29+
self.a = a
30+
31+
def use_a(self) -> None:
32+
print("Using ClassA from ClassB")
33+
```
34+
35+
當你執行 [main.py](main.py) 的時候, 會出現循環引用
36+
37+
```python
38+
from module_a import ClassA
39+
from module_b import ClassB
40+
41+
a = ClassA(None)
42+
b = ClassB(a)
43+
b.use_a()
44+
```
45+
46+
那我們應該如何避免循環引用以及同時有 typing hint 的檢查呢 ❓
47+
48+
這時候介紹 TYPE_CHECKING
49+
50+
[module_a_fix.py](module_a_fix.py)
51+
52+
```python
53+
from typing import TYPE_CHECKING
54+
55+
if TYPE_CHECKING:
56+
from module_b_fix import ClassB
57+
58+
class ClassA:
59+
def __init__(self, b: "ClassB") -> None:
60+
self.b = b
61+
62+
def use_b(self) -> None:
63+
print("Using ClassB from ClassA")
64+
```
65+
66+
注意修改的地方, 首先, `TYPE_CHECKING = False` 預設是 False,
67+
68+
只有在 IDE 的部份才會是 True, 然後需要把 ClassB 加上雙引號變成 `"ClassB"`,
69+
70+
同理, [module_b_fix.py](module_b_fix.py) 一樣的修正方式.
71+
72+
修改完後的 [main_fix.py](main_fix.py) 就可以正常的執行.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from module_a import ClassA
2+
from module_b import ClassB
3+
4+
a = ClassA(None)
5+
b = ClassB(a)
6+
b.use_a()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from module_a_fix import ClassA
2+
from module_b_fix import ClassB
3+
4+
a = ClassA(None)
5+
b = ClassB(a)
6+
b.use_a()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from module_b import ClassB
2+
3+
class ClassA:
4+
def __init__(self, b: ClassB) -> None:
5+
self.b = b
6+
7+
def use_b(self) -> None:
8+
print("Using ClassB from ClassA")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from typing import TYPE_CHECKING
2+
3+
if TYPE_CHECKING:
4+
from module_b_fix import ClassB
5+
6+
class ClassA:
7+
def __init__(self, b: "ClassB") -> None:
8+
self.b = b
9+
10+
def use_b(self) -> None:
11+
print("Using ClassB from ClassA")
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from module_a import ClassA
2+
3+
class ClassB:
4+
def __init__(self, a: ClassA) -> None:
5+
self.a = a
6+
7+
def use_a(self) -> None:
8+
print("Using ClassA from ClassB")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from typing import TYPE_CHECKING
2+
3+
if TYPE_CHECKING:
4+
from module_a_fix import ClassA
5+
6+
class ClassB:
7+
def __init__(self, a: "ClassA") -> None:
8+
self.a = a
9+
10+
def use_a(self) -> None:
11+
print("Using ClassA from ClassB")

0 commit comments

Comments
 (0)