スクリプトからインストールされたパッケージをインポートすると、"AttributeError:module has no attribute" または "ImportError:cannot import name" が発生します。

python exception python-module shadowing


私は、スクリプトの名前持って requests.py その輸入要求パッケージを。スクリプトは、パッケージの属性にアクセスできないか、属性をインポートできません。なぜこれが機能しないのですか、どうすれば修正できますか?

次のコードは AttributeError を発生させます。

import requests

res = requests.get('http://www.google.ca')
print(res)
Traceback (most recent call last):
  File "/Users/me/dev/rough/requests.py", line 1, in <module>
    import requests
  File "/Users/me/dev/rough/requests.py", line 3, in <module>
    requests.get('http://www.google.ca')
AttributeError: module 'requests' has no attribute 'get'

次のコードは ImportError を発生させます。

from requests import get

res = get('http://www.google.ca')
print(res)
Traceback (most recent call last):
  File "requests.py", line 1, in <module>
    from requests import get
  File "/Users/me/dev/rough/requests.py", line 1, in <module>
    from requests import get
ImportError: cannot import name 'get'

または、 requests パッケージ内のモジュールからインポートするコード:

from requests.auth import AuthBase
Traceback (most recent call last):
  File "requests.py", line 1, in <module>
    from requests.auth import AuthBase
  File "/Users/me/dev/rough/requests.py", line 1, in <module>
    from requests.auth import AuthBase
ImportError: No module named 'requests.auth'; 'requests' is not a package



Answer 1 idjaw


これは、 requests.py という名前のローカルモジュールが、使用しようとしているインストール済みの requests モジュールをシャドウするために発生します。現在のディレクトリは sys.path の前に追加されるため、ローカル名がインストールされた名前よりも優先されます。

これが出てきたときのデバッグのヒントは、トレースバックを注意深く見て、問題のスクリプトの名前がインポートしようとしているモジュールと一致していることに気づくことです。

スクリプトで使用した名前に注目してください。

File "/Users/me/dev/rough/requests.py", line 1, in <module>

インポートしようとしているモジュール: requests

名前の衝突を避けるために、モジュールの名前を他のものに変更してください。

Pythonは、 requests.pyc ファイルの隣に( requests.py cファイルを生成する場合があります(Python 3の __pycache__ ディレクトリにあります)。名前を変更した後も削除してください。インタプリタは引き続きそのファイルを参照し、エラーを再現します。しかし、 pyc 内のファイル __pycache__ は、必要がある場合は、あなたのコードには影響を与えませ py ファイルが削除されました。

例では、ファイルの名前変更 my_requests.py を除去 requests.pyc を、そして正常再度印刷を実行 <Response [200]>




Answer 2 Dave Rove


元の質問の作者、および「AttributeError:module has no attribute」文字列を検索する人にとって、受け入れられた回答による一般的な説明は、ユーザーが作成したスクリプトにライブラリとの名前の衝突があるということですファイル名。ただし、問題は、エラーを生成するスクリプトの名前(上記の場合と同じ)でも、そのスクリプトによって明示的にインポートされたライブラリモジュールの名前でも問題ではないことに注意してください。どのファイルが問題の原因であるかを特定するには、少しの調査作業が必要になる場合があります。

問題を説明する例として、10進数の正確な浮動小数点計算に「10進数」ライブラリを使用するスクリプトを作成していて、「 import decimal 」という行を含むスクリプトに「 mydecimal.py 」という名前を付けたとします。 。問題はありませんが、次のエラーが発生します。

AttributeError: 'module' object has no attribute 'Number'

これは、「10進数」ライブラリが標準ライブラリ「numbers」を呼び出すが、代わりに古いスクリプトを見つけるため、以前にnumbers.py 」というスクリプトを記述していた場合に発生します。それを削除したとしても、Pythonがそれをバイトコードに変換し、それを「 numbers.pyc 」としてキャッシュに格納している可能性があるため、問題が解決しない可能性があるため、同様にそれを突き止める必要があります。