Main、vector、entity、physicsという4つの異なるファイルがあります。私はそれがエラーがあるところだと思うので私はすべてのコードを、インポートだけを投稿するつもりはありません。 (あなたが望むなら、私はもっと投稿することができます)
メイン:
import time
from entity import Ent
from vector import Vect
#the rest just creates an entity and prints the result of movement
エンティティ:
from vector import Vect
from physics import Physics
class Ent:
#holds vector information and id
def tick(self, dt):
#this is where physics changes the velocity and position vectors
ベクター:
from math import *
class Vect:
#holds i, j, k, and does vector math
物理:
from entity import Ent
class Physics:
#physics class gets an entity and does physics calculations on it.
それからmain.pyから実行すると、次のようなエラーが表示されます。
Traceback (most recent call last): File "main.py", line 2, in <module> from entity import Ent File ".../entity.py", line 5, in <module> from physics import Physics File ".../physics.py", line 2, in <module> from entity import Ent ImportError: cannot import name Ent
私はPythonにとても慣れていませんが、長い間C++を使ってきました。このエラーは、エンティティを2回、メインで1回、物理学で後でインポートしたことが原因と思われますが、回避策はわかりません。誰も手伝ってくれる?
循環依存インポートがあります。 physics.py
はクラスentity
が定義される前にEnt
からインポートされ、physics
はすでに初期化中のentity
をインポートしようとします。 physics
モジュールからentity
への依存関係を削除します。
循環依存関係を確実に避けるべきですが、pythonではインポートを延期することができます。
例えば:
import SomeModule
def someFunction(arg):
from some.dependency import DependentClass
これは(少なくとも場合によっては)エラーを回避するでしょう。
これは循環依存です。コードを構造的に変更することなく解決できます。 vector
では、entity
をすぐに使用できるようにすることを要求しており、またその逆も同様です。この問題の理由は、from x import y
を使用して、モジュールの準備ができる前にモジュールの内容にアクセスするように求めていることです。これは基本的に同じです
import x
y = x.y
del x
Pythonは循環依存関係を検出し、インポートの無限ループを防ぐことができます。基本的に起こることはモジュールのために空のプレースホルダーが作成されることです(すなわち、それは内容を持っていません)。循環依存モジュールがコンパイルされると、インポートされたモジュールが更新されます。これはこのようなものです。
a = module() # import a
# rest of module
a.update_contents(real_a)
Pythonが循環依存関係を扱うことができるようにするには、import x
スタイルのみを使用しなければなりません。
import x
class cls:
def __init__(self):
self.y = x.y
最上位でモジュールの内容を参照しなくなったので、pythonは循環依存関係の内容に実際にアクセスすることなくモジュールをコンパイルできます。トップレベルとは、関数の内容(例えばy = x.y
)とは対照的に、コンパイル中に実行される行を意味します。モジュールの内容にアクセスする静的変数またはクラス変数も問題を引き起こします。
論理を明確にすることは非常に重要です。この問題は、参照がデッドループになるために発生します。
ロジックを変更したくない場合は、ImportErrorの原因となったインポートステートメントをファイルの他の位置、たとえば末尾に配置します。
from test.b import b2
def a1():
print('a1')
b2()
from test.a import a1
def b1():
print('b1')
a1()
def b2():
print('b2')
if __== '__main__':
b1()
インポートエラーが発生します:
ImportError: cannot import name 'a1'
しかし、次のようにAのfrom test.b import b2の位置を変更すると、
def a1():
print('a1')
b2()
from test.b import b2
そして私たちは欲しいものを手に入れることができます。
b1
a1
b2
別の理由で、私もこのエラーが出ました。
from my_sub_module import my_function
メインスクリプトにはWindowsの行末がありました。 my_sub_module
にはUNIXの行末がありました。それらを同じものに変更することで問題は解決しました。彼らはまた、同じ文字エンコーディングを持つ必要があります。
現在のPythonスクリプトに、インポートした他のモジュールの名前を付けないでください。
解決策: 作業中のPythonスクリプトの名前を変更します
例:
medicaltorch.py
で働いていますfrom medicaltorch import datasets as mt_datasets
medicaltorch
が装着されているモジュールであるために仮定した場合これはImportError
で失敗します。作業中のPythonスクリプトの名前を1に変更するだけです。
まだこれを見ないでください - これは信じられないほど愚かですが、正しい変数/関数をインポートしていることを確認してください。
このエラーが出ました
ImportError:名前IMPLICIT_WAITをインポートできません
私の変数は実際にはIMPLICIT_TIMEOUT
だったからです。
正しい名前を使用するようにインポートを変更したときに、エラーが発生しなくなりました。???? ♂️
これは循環依存です。この問題を解決するには、必要な場所に import モジュールまたはクラスまたは関数を使用します。このアプローチを使えば循環依存を修正できます
A.py
from B import b2
def a1():
print('a1')
b2()
B.py
def b1():
from A import a1
print('b1')
a1()
def b2():
print('b2')
if __== '__main__':
b1()