web-dev-qa-db-ja.com

AttributeError: 'module'オブジェクトには属性がありません

私は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'

エラーはどういう意味ですか?どうやって直すの?

160
Stephen Hsu

あなたは相互にトップレベルのインポートをしていますが、これはほとんど常に悪い考えです。

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回目以降はモジュールをインポートするのは速い操作。)

165
RichieHindle

誤って標準のPythonモジュールの1つと同じ名前のモジュールを命名したときにもこのエラーが発生しました。例えば。私はPythonライブラリモジュールでもあるcommandsというモジュールを持っていました。これは私のローカル開発環境では正しく機能していたのですが、Google App Engine上で実行した際に指定されたエラーで失敗したため、追跡するのが難しいことがわかりました。

81
lucrussell

問題はモジュール間の循環依存です。 abをインポートし、baをインポートします。しかし、そのうちの1つを最初にロードする必要があります - この場合、pythonはaの前にモジュールbを初期化し、aでアクセスしようとするとまだb.hi()は存在しません。

40
sth

間違った方法でインポートされたenumを参照することでこのエラーが発生しました。

from package import MyEnumClass
# ...
# in some method:
return MyEnumClass.Member

正しいインポート:

from package.MyEnumClass import MyEnumClass

誰かに役立つことを願っています

18
Stoyan

モジュールが実際にインポートされなかったため、このエラーが発生しました。コードは次のようになりました。

import a.b, a.c

# ...

something(a.b)
something(a.c)
something(a.d)  # My addition, which failed.

最後の行はAttributeErrorです。 aのサブモジュール(a.ba.c)が明示的ににインポートされたことに気付かなかったため、importステートメントは実際にaをインポートしたと想定しました。

7
Dag Høidahl

私はgitから古いバージョンのリポジトリをチェックアウトしたときにこの問題に遭遇しました。 Gitは私の.pyファイルを置き換えましたが、追跡されていない.pycファイルは残しました。 .pyファイルと.pycファイルが同期していなかったので、.pyファイルのimportコマンドは.pycファイルで対応するモジュールを見つけることができませんでした。

解決策は、単に.pycファイルを削除し、それらが自動的に再生成されるようにすることでした。

3
craq

私は同じ問題に直面しました。 reloadを使用して修正しました。

import the_module_name
from importlib import reload
reload(the_module_name)
2
Jiu

上記のすべての答えは素晴らしいですが、ここでチャイムしたいと思います。上記の問題を見つけられなかった場合は、職場環境を整えてください。それは私のために働きました。

2
Jian

onubuntu 18.04virtualenvpython.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

0
Behzad Sezar

循環インポートは問題を引き起こしますが、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の最初の実行はモジュールをインポートすることとして登録されます。

0
Hot.PxL

@ MD5私と同じ、モジュール名を変更するか、関数を直接インポートしてください

0
Patrick

よくわからないが、以下の変更が私の問題を分類した。

私はファイル名とインポート名が同じであることを持っていました。しかし、ファイル名を変更することで問題は解決しました。

それが役立つように願っています

0
MD5