Type Hinting in Python Without Cyclic Imports
In an attempt to split a large class into two smaller ones, you encounter the issue of cyclic imports. The "main" class imports the mixin class, and the mixin class references the "main" class in its type hint. This results in an import cycle, preventing the type hinting from working properly.
To resolve this, you can consider the following approach:
<code class="python"># main.py from __future__ import annotations from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from mixin import MyMixin class Main(object): def func1(self, xxx: Any): ...</code>
<code class="python"># mixin.py from __future__ import annotations from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from main import Main class MyMixin(object): def func2(self: Main, xxx: Any): ...</code>
In this example, Python's TYPE_CHECKING constant is used to conditionally import the "main" class. When running the code, the import statement is skipped due to the constant being False. However, type-checking tools like mypy interpret the code within the if TYPE_CHECKING block and recognize the type annotation for func2.
Another approach involves using a forward reference:
<code class="python"># mixin.py from __future__ import annotations from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from main import Main class MyMixin(object): def func2(self, xxx: 'Main'): ...</code>
Here, the type annotation for func2 is a string representing the name of the class that will be imported later. Both approaches require the use of Python 3.7 or higher to work effectively with type hints.
Remember that using mixins and type hinting may require additional structuring in your code. For example, mypy recommends creating an Abstract Base Class (ABC) that both your "main" and mixin classes inherit from. This can improve the accuracy of type checking.
The above is the detailed content of How to Resolve Cyclic Imports for Type Hinting in Python?. For more information, please follow other related articles on the PHP Chinese website!