私は2つのpythonモジュールを持っています。
a.py
import b
def hello():
print "hello"
print "a.py"
print hello()
print b.hi()
b.py
import a
def hi():
print "hi"
a.py
を実行すると、次のようになります。
AttributeError: 'module' object has no attribute 'hi'
エラーはどういう意味ですか?どうやって直すの?
あなたは相互にトップレベルのインポートをしていますが、これはほとんど常に悪い考えです。
Pythonで本当に相互インポートが必要な場合は、それを行う方法は関数内でインポートすることです。
# In b.py:
def cause_a_to_do_something():
import a
a.do_something()
A.pyは問題なく安全にimport b
を実行できるようになりました。
(一見するとcause_a_to_do_something()
は呼び出すたびにimport
を実行するので非常に非効率的に見えるかもしれませんが、実際にはインポート作業は最初に行われるだけです。2回目以降はモジュールをインポートするのは速い操作。)
誤って標準のPythonモジュールの1つと同じ名前のモジュールを命名したときにもこのエラーが発生しました。例えば。私はPythonライブラリモジュールでもあるcommands
というモジュールを持っていました。これは私のローカル開発環境では正しく機能していたのですが、Google App Engine上で実行した際に指定されたエラーで失敗したため、追跡するのが難しいことがわかりました。
問題はモジュール間の循環依存です。 a
はb
をインポートし、b
はa
をインポートします。しかし、そのうちの1つを最初にロードする必要があります - この場合、pythonはa
の前にモジュールb
を初期化し、a
でアクセスしようとするとまだb.hi()
は存在しません。
間違った方法でインポートされたenumを参照することでこのエラーが発生しました。
from package import MyEnumClass
# ...
# in some method:
return MyEnumClass.Member
正しいインポート:
from package.MyEnumClass import MyEnumClass
誰かに役立つことを願っています
モジュールが実際にインポートされなかったため、このエラーが発生しました。コードは次のようになりました。
import a.b, a.c
# ...
something(a.b)
something(a.c)
something(a.d) # My addition, which failed.
最後の行はAttributeError
です。 a
のサブモジュール(a.b
とa.c
)が明示的ににインポートされたことに気付かなかったため、import
ステートメントは実際にa
をインポートしたと想定しました。
私はgitから古いバージョンのリポジトリをチェックアウトしたときにこの問題に遭遇しました。 Gitは私の.py
ファイルを置き換えましたが、追跡されていない.pyc
ファイルは残しました。 .py
ファイルと.pyc
ファイルが同期していなかったので、.py
ファイルのimport
コマンドは.pyc
ファイルで対応するモジュールを見つけることができませんでした。
解決策は、単に.pyc
ファイルを削除し、それらが自動的に再生成されるようにすることでした。
私は同じ問題に直面しました。 reload
を使用して修正しました。
import the_module_name
from importlib import reload
reload(the_module_name)
上記のすべての答えは素晴らしいですが、ここでチャイムしたいと思います。上記の問題を見つけられなかった場合は、職場環境を整えてください。それは私のために働きました。
onubuntu 18.04(virtualenv、python.3.6.x)、次のreloadスニペットsolved私にとっての問題:
main.py
import my_module # my_modyle.py
from importlib import reload # reload
reload(my_module)
print(my_module)
print(my_modeule.hello())
ここで:
|--main.py
|--my_module.py
詳細についてはdocumentationcheck: here
循環インポートは問題を引き起こしますが、Pythonにはそれを軽減する方法が組み込まれています。
問題は、python a.py
を実行すると、a.py
は実行されますが、モジュールとしてインポートされたことはマークされません。そのため、a.py
- >モジュールbのインポート - >モジュールaのインポート - >モジュールbのインポートとなります。 bは現在インポートされており、Pythonはそれに対して保護しているので、最後のインポートは何もしません。そしてbは今のところ空のモジュールです。そのため、b.hi()
を実行すると、何も見つかりません。
実行されたb.hi()
はa.py
- > module b - > module aの間であり、直接a.py
内ではないことに注意してください。
あなたの特定の例では、あなたはトップレベルでpython -c 'import a'
を実行することができます、それでa.py
の最初の実行はモジュールをインポートすることとして登録されます。
@ MD5私と同じ、モジュール名を変更するか、関数を直接インポートしてください
よくわからないが、以下の変更が私の問題を分類した。
私はファイル名とインポート名が同じであることを持っていました。しかし、ファイル名を変更することで問題は解決しました。
それが役立つように願っています