Python で循環インポートを修正するさまざまな方法
Python で 循環インポート を見たことがありますか?まあ、これはデザインや構造に何か問題があることを示す非常に一般的なコードの匂いです。
循環インポートの例
循環インポートはどのように行われますか? このインポート エラーは通常、相互に依存する 2 つ以上のモジュールが完全に初期化される前にインポートしようとしたときに発生します。
module_1.py と module_2.py という 2 つのモジュールがあるとします。
# module_1.py from module_2 import ModY class ModX: mody_obj = ModY()
# module_2.py from module_1 import ModX class ModY: modx_obj = ModX()
上記のコード スニペットでは、module_1 と module_2 は両方とも相互に依存しています。
module_1 の mody_obj の初期化は module_2 に依存し、 module_2 の modx_obj の初期化は module_1 に依存します。
これは循環依存関係と呼ばれるものです。両方のモジュールが相互にロードしようとすると、インポート ループでスタックします。
module_1.py を実行すると、次のトレースバックが得られます。
Traceback (most recent call last): File "module_1.py", line 1, in <module> from module_2 import ModY File "module_2.py", line 1, in <module> from module_1 import ModX File "module_1.py", line 1, in <module> from module_2 import ModY ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
このエラーは、循環インポートの状況を説明しています。プログラムが module_2 から ModY をインポートしようとしたとき、その時点では module_2 は完全に初期化されていませんでした (moddX を module_1 からインポートしようとする別のインポート ステートメントのため)。
Python で循環インポートを修正するにはどうすればよいですか? Python で循環インポートを削除するにはさまざまな方法があります。
Python での循環インポートを修正する
コードを共通ファイルに移動する
インポートエラーを回避するためにコードを共通ファイルに移動し、そのファイルからモジュールをインポートしてみることができます。
# main.py ----> common file class ModX: pass class ModY: pass
上記のコード スニペットでは、ModX クラスと ModY クラスを共通ファイル (main.py) に移動しました。
# module_1.py from main import ModY class Mod_X: mody_obj = ModY()
# module_2.py from main import ModX class Mod_Y: modx_obj = ModX()
ここで、module_1 と module_2 が main からクラスをインポートすることで、循環インポートの状況が修正されます。
このアプローチには問題があり、コードベースが非常に大きくなり、コードを別のファイルに移動するのが危険になる場合があります。
インポートをモジュールの最後に移動します
モジュールの最後に import ステートメントを移動できます。これにより、別のモジュールをインポートする前にモジュールを完全に初期化する時間が与えられます。
# module_1.py class ModX: pass from module_2 import ModY class Mod_X: mody_obj = ModY()
# module_2.py class ModY: pass from module_1 import ModX
クラス/関数スコープ内のモジュールのインポート
クラスまたは関数のスコープ内でモジュールをインポートすると、循環インポートを回避できます。これにより、クラスまたは関数が呼び出された場合にのみモジュールをインポートできるようになります。これは、メモリの使用を最小限に抑えたい場合に関係します。
# module_1.py class ModX: pass class Mod_X: from module_2 import ModY mody_obj = ModY()
# module_2.py class ModY: pass class Mod_Y: from module_1 import ModX modx_obj = ModX()
インポート ステートメントを、それぞれ module_1 と module_2 のクラス Mod_X と Mod_Y スコープ内に移動しました。
module_1 または module_2 を実行すると、循環インポート エラーは発生しません。ただし、このアプローチでは、クラスのスコープ内でのみクラスにアクセスできるようになるため、グローバルにインポートを利用することはできません。
モジュール名/エイリアスの使用
このようにモジュール名または単なるエイリアスを使用すると、問題が解決します。これにより、実行時まで循環依存関係を延期することで、両方のモジュールを完全にロードできるようになります。
# module_1.py from module_2 import ModY class ModX: mody_obj = ModY()
# module_2.py from module_1 import ModX class ModY: modx_obj = ModX()
importlibライブラリの使用
importlib ライブラリを使用してモジュールを動的にインポートすることもできます。
Traceback (most recent call last): File "module_1.py", line 1, in <module> from module_2 import ModY File "module_2.py", line 1, in <module> from module_1 import ModX File "module_1.py", line 1, in <module> from module_2 import ModY ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
# main.py ----> common file class ModX: pass class ModY: pass
Python パッケージの循環インポート
通常、循環インポート 同じパッケージ内のモジュールから取得されます。複雑なプロジェクトでは、パッケージ内にパッケージが存在するため、ディレクトリ構造も複雑になります。
これらのパッケージとサブパッケージには、モジュールへのアクセスを容易にする __init__.py ファイルが含まれています。ここで、モジュール間で意図せず循環依存関係が発生することがあります。
次のディレクトリ構造があります。
# module_1.py from main import ModY class Mod_X: mody_obj = ModY()
パッケージ mainpkg と main.py ファイルがあります。 mainpkg 内には 2 つのサブパッケージ modpkg_x と modpkg_y があります。
modpkg_x および modpkg_y 内の各 Python ファイルは次のようになります。
mainpkg/modpkg_x/__init__.py
# module_2.py from main import ModX class Mod_Y: modx_obj = ModX()
このファイルは、module_1 と module_1_1 から両方のクラス (ModX と ModA) をインポートします。
mainpkg/modpkg_x/module_1.py
# module_1.py class ModX: pass from module_2 import ModY class Mod_X: mody_obj = ModY()
module_1 は module_2 からクラス ModY をインポートします。
mainpkg/modpkg_x/module_1_1.py
# module_2.py class ModY: pass from module_1 import ModX
module_1_1 は何もインポートしません。どのモジュールにも依存しません。
mainpkg/modpkg_y/__init__.py
# module_1.py class ModX: pass class Mod_X: from module_2 import ModY mody_obj = ModY()
このファイルは、module_2 からクラス ModY をインポートします。
mainpkg/modpkg_y/module_2.py
# module_2.py class ModY: pass class Mod_Y: from module_1 import ModX modx_obj = ModX()
module_2 は module_1_1 からクラス ModA をインポートします。
main.py ファイル内には次のコードがあります。
root_dir/main.py
# module_1.py import module_2 as m2 class ModX: def __init__(self): self.mody_obj = m2.ModY()
メイン ファイルは module_2 からクラス ModY をインポートします。このファイルは module_2.
に依存しています。ここでインポート サイクルを視覚化すると、modpkg_x および modpkg_y 内の __init__.py ファイルを無視して次のようになります。
メイン ファイルが module_2 に依存し、 module_1 も module_2 に依存し、 module_2 が module_1_1 に依存していることがわかります。インポートサイクルはありません。
しかし、モジュールは __init__.py ファイルに依存しているため、__init__.py ファイルが最初に初期化され、モジュールが再インポートされます。
現在のインポート サイクルは次のようになります。
これにより、module_1_1 が module_1 に依存するようになりました。これは偽の依存関係です。
この場合は、サブパッケージの __init__.py ファイルを空にし、別の __init__.py ファイルを使用すると、パッケージ レベルでインポートを一元化できます。
# module_1.py from module_2 import ModY class ModX: mody_obj = ModY()
この構造では、mainpkg 内に別のサブパッケージ subpkg を追加しました。
メインpkg/サブpkg/__init__.py
# module_2.py from module_1 import ModX class ModY: modx_obj = ModX()
これにより、内部モジュールを単一のソースからインポートできるようになり、相互インポートの必要性が減ります。
これで、main.py ファイル内の import ステートメントを更新できるようになりました。
root_dir/main.py
Traceback (most recent call last): File "module_1.py", line 1, in <module> from module_2 import ModY File "module_2.py", line 1, in <module> from module_1 import ModX File "module_1.py", line 1, in <module> from module_2 import ModY ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
これにより、同じパッケージ内のモジュール間の循環依存関係の問題が解決されます。
結論
Python での循環依存関係またはインポートは コードの匂い であり、コードの深刻な再構築とリファクタリングを示します。
Python での循環依存関係を回避するには、上記の方法のいずれかを試すことができます。
?この記事が気に入ったら、興味があるかもしれない他の記事
✅Flask でのテンプレートの継承と例
✅exec() と eval() の違いと例
✅Python でのグローバル キーワードの使用を理解します。
✅Python の型ヒント: 関数、戻り値、変数。
✅関数定義でスラッシュとアスタリスクが使用される理由。
✅学習率は ML モデルと DL モデルにどのような影響を与えますか?
今回は以上です。
コーディングを続けてください✌✌。
以上がPython で循環インポートを修正するさまざまな方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undress AI Tool
脱衣画像を無料で

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

API認証を扱うための鍵は、認証方法を正しく理解して使用することです。 1。Apikeyは、通常、リクエストヘッダーまたはURLパラメーターに配置されている最も単純な認証方法です。 2。BasicAuthは、内部システムに適したBase64エンコード送信にユーザー名とパスワードを使用します。 3。OAUTH2は、最初にclient_idとclient_secretを介してトークンを取得し、次にリクエストヘッダーにbearertokenを持ち込む必要があります。 4。トークンの有効期限に対処するために、トークン管理クラスをカプセル化し、トークンを自動的に更新できます。要するに、文書に従って適切な方法を選択し、重要な情報を安全に保存することが重要です。

Pythonでは、ループを使用してタプルを通過する方法には、要素を直接繰り返し、インデックスと要素を同時に取得し、ネストされたタプルを処理する方法が含まれます。 1。インデックスを管理せずに、for loopを直接使用して、各要素に順番に各要素にアクセスします。 2。enumerate()を使用して、同時にインデックスと値を取得します。デフォルトのインデックスは0で、開始パラメーターも指定できます。 3.ネストされたタプルはループで開梱できますが、サブタプル構造が一貫していることを確認する必要があります。さらに、タプルは不変であり、ループでコンテンツを変更することはできません。不要な値は\ _によって無視できます。エラーを避けるために、トラバースする前にタプルが空であるかどうかを確認することをお勧めします。

Pythonで大きなJSONファイルを効率的に処理する方法は? 1. IJSONライブラリを使用して、アイテムごとの解析を介してメモリオーバーフローをストリーミングして回避します。 2. JSonlines形式の場合は、行ごとに読み取り、json.loads()で処理できます。 3.または、大きなファイルを小さな部分に分割してから、個別に処理します。これらの方法は、メモリ制限の問題を効果的に解決し、さまざまなシナリオに適しています。

はい、apythonclasscanhavemultipleconstructorsthroughtertechniques.1.Defaultargumentsionthodto __tododtoallowdodtoibleInitialization with varyingnumbersofparameters.2.declassmethodsasasaLternativeconstructorsoriable rerableible bulible clurecreatureati

Pythonでは、range()関数を使用してforループを使用することは、ループの数を制御する一般的な方法です。 1.ループの数を知っている場合、またはインデックスごとに要素にアクセスする必要がある場合に使用します。 2。範囲(STOP)から0からSTOP-1、範囲(開始、停止)からSTOP-1、範囲(開始、停止)がステップサイズを追加します。 3.範囲には最終値が含まれておらず、Python 3のリストの代わりに反復可能なオブジェクトを返すことに注意してください。 4.リスト(range())を介してリストに変換し、ネガティブなステップサイズを逆順に使用できます。

Quantum Machine Learning(QML)を開始するには、優先ツールがPythonであり、Pennylane、Qiskit、Tensorflowquantum、Pytorchquantumなどのライブラリをインストールする必要があります。次に、Pennylaneを使用して量子ニューラルネットワークを構築するなど、例を実行してプロセスに慣れます。次に、データセットの準備、データエンコード、パラメトリック量子回路の構築、古典的なオプティマイザートレーニングなどの手順に従ってモデルを実装します。実際の戦闘では、最初から複雑なモデルを追求したり、ハードウェアの制限に注意を払ったり、ハイブリッドモデル構造を採用したり、開発をフォローアップするための最新のドキュメントと公式文書を継続的に参照することを避ける必要があります。

Pythonを使用してWebAPIを呼び出してデータを取得するための鍵は、基本的なプロセスと共通のツールをマスターすることです。 1.リクエストを使用してHTTPリクエストを開始することが最も直接的な方法です。 GETメソッドを使用して応答を取得し、json()を使用してデータを解析します。 2。認証が必要なAPIの場合、ヘッダーからトークンまたはキーを追加できます。 3.応答ステータスコードを確認する必要があります。respons.raise_for_status()を使用して、例外を自動的に処理することをお勧めします。 4.ページングインターフェイスに直面すると、さまざまなページを順番にリクエストし、遅延を追加して周波数制限を回避できます。 5.返されたJSONデータを処理する場合、構造に従って情報を抽出する必要があり、複雑なデータをデータに変換できます

PythonのOnelineifelseは、XifconditionElseyとして書かれた3成分演算子であり、単純な条件付き判断を簡素化するために使用されます。 Status = "Adult" ifage> = 18else "minor"など、可変割り当てに使用できます。また、defget_status(age):urtuel "adult" ifage> = 18else "minor"などの関数で結果を直接返すためにも使用できます。 result = "a" iなど、ネストされた使用はサポートされていますが
