[解決済み】周期的インポートを使用しないPythonのタイプヒンティング
質問
巨大なクラスを2つに分割しようとしているのですが、基本的には "main" クラスと、追加機能を持つミキシンに、以下のように分割します。
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つのファイルに分割して、すべての "connection" を維持し、IDE が自動補完や型を知ることによって得られる他のすべての利点を提供できる方法はありますか?
どのように解決するのですか?
一般的にインポートサイクルを処理するための非常にエレガントな方法はありません、私は怖いです。あなたの選択肢は、周期的な依存関係を取り除くためにコードを再設計するか、それが実行可能でない場合は、次のようなことを行うことです。
# 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+を使用している場合、少なくとも明示的な文字列アノテーションを提供する必要はありません。 PEP 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でmixinを使うには、現在持っているものよりもう少し構造が必要になりそうです。mypy
は、次のようなアプローチを推奨しています。
というのは、基本的に
deceze
が説明しているのは、ABCを作成することで、あなたの
Main
と
MyMixin
クラスが継承します。Pycharmのチェッカーを満足させるために、同じようなことをする必要があったとしても、私は驚かないでしょう。
関連
-
ピローによる動的キャプチャ認識のためのPythonサンプルコード
-
[解決済み】ilocが「IndexError: single positional indexer is out-of-bounds」を出す。
-
[解決済み】Pythonスクリプトで「Expected 2D array, got 1D array instead: 」というエラーが発生?
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Pythonで2つのリストを連結する方法は?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】Python 3での相対インポート
-
[解決済み】メソッドの型ヒントは、どのようにエンクロージャクラスの型を使用するのですか?
-
[解決済み】Pythonに三項条件演算子はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
python call matlab メソッドの詳細
-
PicgoのイメージベッドツールをPythonで実装する
-
PythonはWordの読み書きの変更操作を実装している
-
Python Pillow Image.save jpg画像圧縮問題
-
Pythonの画像ファイル処理用ライブラリ「Pillow」(グラフィックの詳細)
-
[解決済み】ImportError: sklearn.cross_validation という名前のモジュールがない。
-
[解決済み】RuntimeWarning: 割り算で無効な値が発生しました。
-
[解決済み】「RuntimeError: dictionary changed size during iteration」エラーを回避する方法とは?
-
[解決済み】csv.Error:イテレータはバイトではなく文字列を返すべき
-
[解決済み】Django: ImproperlyConfigured: SECRET_KEY 設定は空であってはならない