web-dev-qa-db-ja.com

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

リクエストパッケージをインポートする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
42
idjaw

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

これが発生した場合の追加のデバッグのヒントは、トレースバックを注意深く見て、問題のスクリプトの名前がインポートしようとしているモジュールと一致していることを認識することです。

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

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

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

モジュールの名前を別の名前に変更して、名前の衝突を回避します。

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

この例では、ファイルの名前をmy_requests.pyに変更し、requests.pycを削除して再実行すると、<Response [200]>が正常に出力されます。

50
idjaw

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

問題を説明する例として、10進数での正確な浮動小数点計算に「10進数」ライブラリーを使用するスクリプトを作成し、「mydecimal.py」という行に「import decimal "。そのいずれにも問題はありませんが、次のエラーが発生することがわかります。

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

これは、以前が "numbers.py"というスクリプトを記述した場合に発生します。これは、「10進」ライブラリが標準ライブラリ「numbers」を呼び出し、代わりに古いスクリプトを検出するためです。削除したとしても、pythonはそれをバイトコードに変換し、キャッシュに "numbers.pyc"として保存した可能性があるため、問題が解決しない可能性があります。同様にそれを追い詰める。

9
Dave Rove