web-dev-qa-db-ja.com

ImportError:名前Xをインポートできません

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回、物理学で後でインポートしたことが原因と思われますが、回避策はわかりません。誰も手伝ってくれる?

396
jsells

循環依存インポートがあります。 physics.pyはクラスentityが定義される前にEntからインポートされ、physicsはすでに初期化中のentityをインポートしようとします。 physicsモジュールからentityへの依存関係を削除します。

404
Teemu Ikonen

循環依存関係を確実に避けるべきですが、pythonではインポートを延期することができます。

例えば:

import SomeModule

def someFunction(arg):
    from some.dependency import DependentClass

これは(少なくとも場合によっては)エラーを回避するでしょう。

116
bharling

これは循環依存です。コードを構造的に変更することなく解決できます。 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)とは対照的に、コンパイル中に実行される行を意味します。モジュールの内容にアクセスする静的変数またはクラス変数も問題を引き起こします。

95
Dunes

論理を明確にすることは非常に重要です。この問題は、参照がデッドループになるために発生します。

ロジックを変更したくない場合は、ImportErrorの原因となったインポートステートメントをファイルの他の位置、たとえば末尾に配置します。

a.py

from test.b import b2

def a1():
    print('a1')
    b2()

b.py

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の位置を変更すると、

a.py

def a1():
    print('a1')
    b2()

from test.b import b2

そして私たちは欲しいものを手に入れることができます。

b1
a1
b2
16
g10guang

別の理由で、私もこのエラーが出ました。

from my_sub_module import my_function

メインスクリプトにはWindowsの行末がありました。 my_sub_moduleにはUNIXの行末がありました。それらを同じものに変更することで問題は解決しました。彼らはまた、同じ文字エンコーディングを持つ必要があります。

12
marengaz

現在のPythonスクリプトに、インポートした他のモジュールの名前を付けないでください。

解決策: 作業中のPythonスクリプトの名前を変更します

例:

  1. あなたはmedicaltorch.pyで働いています
  2. そのスクリプトでは、あなたが持っている:from medicaltorch import datasets as mt_datasetsmedicaltorchが装着されているモジュールであるために仮定した場合

これはImportErrorで失敗します。作業中のPythonスクリプトの名前を1に変更するだけです。

4
Paul

まだこれを見ないでください - これは信じられないほど愚かですが、正しい変数/関数をインポートしていることを確認してください。

このエラーが出ました

ImportError:名前IMPLICIT_WAITをインポートできません

私の変数は実際にはIMPLICIT_TIMEOUTだったからです。

正しい名前を使用するようにインポートを変更したときに、エラーが発生しなくなりました。???? ‍♂️

3
Nick Brady

これは循環依存です。この問題を解決するには、必要な場所に 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() 
1
a.patidar