Pythonモジュールがサブモジュールをインポートしないことがあるのはなぜですか?


88

今日は何か変なことに気づき、説明したいと思います。私はこれを質問として表現する方法さえ100%確信していなかったので、グーグルは問題外です。奇妙な理由で、ロギングモジュールはモジュールlogging.handlersにアクセスできません。あなたが私を信じていないなら、あなた自身でそれを試してください:

>>> import logging
>>> logging.handlers
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'handlers'
>>> import logging.handlers
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python2.6/logging/handlers.pyc'>

なぜこれが起こるのか誰かが説明できますか?

回答:


119

Pythonでは、モジュールにアクセスする前にモジュールをインポートする必要があります。import loggingロギングモジュールのみをインポートします。loggingサブモジュールを含むパッケージであることが起こりますが、それらのサブモジュールはまだ自動的にロードされません。したがって、logging.handlersアクセスする前に明示的にインポートする必要があります。

なぜこれらの追加のインポートが必要ないように見えるのか疑問に思っている場合:一部のパッケージは、インポート時にサブモジュールの一部またはすべてをインポートします-__init__.pyファイルでそれらのインポートを行うだけです。他の場合では、あなたがインポートした他の何か、またインポートされたものかもしれませんlogging.handlers。どのコードがインポートを行うかは問題ではありません。プロセス内の何かlogging.handlersがアクセスする前にインポートされる限り、そこにあります。また、パッケージのように見えるモジュールが、実際には1つではない場合もosありos.pathます。osはパッケージではなく、(プラットフォーム用の)正しい他のモジュールをインポートして呼び出すpathだけなので、としてアクセスできますos.path


4

私はPythonも初めてで、たくさんの練習を積んだ後、パッケージ(フォルダー)、モジュール(.py)、クラス、変数などを区別できるようになりました。

フォルダのいずれかをPythonパッケージにしたい場合-含まれている必要があります __init__.py空のファイルでもファイルがます!!!

トーマスが言ったように、あなたは追加のモジュールをインポートすることができます __init__.p応じてyにます!!! しかし、モジュール/パッケージはそれをインポートした後にのみアクセス可能です...

モジュールからすべてをインポートしたい場合は、

from logging import *

残りは、以下のようにハンドラモジュールにもアクセスできます。

from logging import handlers
print dir(handlers)


5
使用しないでくださいfrom module import *。ほとんどの場合、それは間違いです。
Thomas Wouters 2010

パッケージ内のすべてを自動的にインポートする場合は、すべてinit .pyに設定して、どこかで「from package import *」を実行するのではなく、init.pyでそれらのインポートを実行します
Thomas Wouters 2010

2
@Pete:あいまいさと競合につながる標準の名前空間を「汚染」するため、私が持っていてimport zipperzipper.open()あなたが私が呼んでいたオープンを正確に知っているなら。逆に、from zipper import *それに続くのopen()は、組み込みのopenまたはzipper.openなどです。import zipper as zタイピングにうんざりしている場合は、はるかに好まれますzipper
msw 2010

3
@Pete:名前空間の一部を無意識のうちに上書きする可能性があるため、これも問題です。numpy import *numpyのすべてをインポートしないと一部のnumpy関数が機能しないため(IMOの部分にひどい設計上の欠陥)、numpyには膨大な数のオブジェクトがインポートされるため、以前はfromを使用していました。結局、多くの関数を上書きしてしまいました(コピーは1つだったと思います...疲れすぎて確認できません)。numpyを使いすぎて、何度も入力するのに耐えられない場合は、numpyをnpとしてインポートします。
chriscauley 2010

2
@dustynachos、どのnumpy関数にその欠陥がありますか?
Winston Ewert 2013

2

トーマス・ウーターズはこの質問に非常によく答えましたが、残念ながら、私は元のドキュメントで答えを見つけた後で初めてこの質問を見つけました。そのために、将来的に検索エンジンの上部に表示されることを期待して、これに追加すると思いました。

質問

エラーが発生するのはなぜですか: ' AttributeError:module' module_name 'には属性がありません' sub_module_name 'エディター(Visual Codeなど)がサブモジュール名を自動入力しても表示されます:

 import module_name
 module_name.sub_module_name(parameter)

回答

エディターは、Pythonの動作ではなく、プロジェクトのファイル構造に基づいてオートコンプリートを作成しています。モジュールをインポートするときに、サブモジュールは「自動的に」インポートされません。参考Pythonドキュメントどのように「自動的に」インポートサブモジュールへの詳細については、使用して

 import module_name

この回答の主な貢献は、「モジュール」または「パッケージ」をインポートしようとしたときにAttributeErrorが追加されることです。

これが誰かを助けることを願っています!


1

私は最近、同じ奇妙な状況に直面しました。したがって、サードパーティのlibインポートを削除したに違いありません。含まれているfrom logging import handlersまたはfrom logging import *提供されたlibを削除しました handlers。そして、他のスクリプトでは、あなたは次のようなものを持っていてimport logging、ちょうど使用しましたlogging.handlers、そしてあなたはそれが私がしたように物事が機能する方法であると思いました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.