循環インポートなしのPython型ヒント 質問する

循環インポートなしのPython型ヒント 質問する

私は巨大なクラスを 2 つに分割しようとしています。基本的には、次のように「メイン」クラスと追加機能を持つミックスインに分割します。

main.pyファイル:

import mymixin.py

class Main(object, MyMixin):
    def func1(self, xxx):
        ...

mymixin.pyファイル:

class MyMixin(object):
    def func2(self: Main, xxx):  # <--- note the type hint
        ...

さて、これは問題なく動作しますが、 の型ヒントはMyMixin.func2当然動作しません。 をインポートできません。main.py循環インポートが発生し、ヒントがないとエディター (PyCharm) が何が何だか分からないからですself

私は Python 3.4 を使用していますが、解決策が見つかった場合は 3.5 に移行するつもりです。

クラスを 2 つのファイルに分割し、すべての「接続」を維持して、IDE が引き続き自動補完や、型を認識することによって得られるその他のすべての便利な機能を提供できるようにする方法はありますか?

ベストアンサー1

残念ながら、一般的にインポート サイクルを処理するための非常にエレガントな方法はありません。選択肢としては、循環依存関係を削除するようにコードを再設計するか、それが実行できない場合は次のようにするかのいずれかです。

# some_file.py

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from main import Main

class MyObject(object):
    def func2(self, some_param: 'Main'):
        ...

定数TYPE_CHECKINGは常にFalse実行時にあるため、インポートは評価されませんが、mypy (およびその他の型チェック ツール) はそのブロックの内容を評価します。

また、シンボルは実行時に使用できないMainため、型注釈を文字列にして、事実上前方宣言する必要があります。Main

Python 3.7以降を使用している場合は、明示的な文字列注釈を提供する必要がなくなります。ペップ563:

# some_file.py

from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from main import Main

class MyObject(object):
    # Hooray, cleaner annotations!
    def func2(self, some_param: Main):
        ...

インポートfrom __future__ import annotationsにより、すべての型ヒントが文字列になり、それらの評価がスキップされます。これにより、ここでのコードが多少人間工学的になります。

そうは言っても、mypy でミックスインを使用するには、現在よりも少し構造化が必要になる可能性があります。Mypyアプローチを推奨する基本的に、これは、クラスとクラスのdeceze両方が継承する ABC を作成するための記述です。Pycharm のチェッカーを満足させるために、同様のことを行う必要が生じたとしても、私は驚かないでしょう。MainMyMixin

おすすめ記事