2016-08-12 10 views
5

from foo import barimport foo.bar as barの違いは何ですか?Pythonのインポートについての説明

Pythonの名前空間とスコープに関する限り、違いはありますか? bar(例えば、whateverという関数)を使用する場合は、いずれの方法でもbar.whatever()と呼びます。

私は作業しているコードベースに両方のスタイルのインポートを見ていますが、違いが何であれ、それが何であるか、そしてもっと「Pythonic」アプローチと見なされるのは疑問でした。

答えて

4

fooパッケージ内barモジュールやパッケージがあるときのために、そしてbarすべてでモジュールされていない場合は、両方の違いが、あります。次fooパッケージ考慮

__init__.pyファイルがあまりにもグローバル名barを定義する場合

foo/ 
    __init__.py 
    bar.py 

、その後、最初の例では、オブジェクトをインポートします。 2番目の例では、bar.pyモジュールがインポートされます。

$ ls -1 foo/ 
__init__.py 
bar.py 
$ cat foo/__init__.py 
bar = 'from the foo package' 
$ cat foo/bar.py 
baz = 'from the foo.bar module' 
$ python 
Python 2.7.12 (default, Aug 3 2016, 18:12:10) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from foo import bar 
>>> bar 
'from the foo package' 
>>> import foo.bar as bar 
>>> bar 
<module 'foo.bar' from 'foo/bar.pyc'> 
>>> bar.baz 
'from the foo.bar module' 
>>> from foo import bar 
>>> bar 
<module 'foo.bar' from 'foo/bar.pyc'> 

他の場合は、ここで:foo.barモジュールは、Pythonのインポート機構が__init__.pyのグローバル任意の既存barを置き換え、fooパッケージに名前barを設定し、インポートされた後しかし

なしbar.pyサブモジュールがあります。 fooは、パッケージまたは単純なモジュールのいずれかです。その場合にはfrom foo import barは常にfooモジュール内のオブジェクトを探します、とimport foo.bar as barは常に失敗します。

$ cat foo.py 
bar = 'from the foo module' 
$ python 
Python 2.7.12 (default, Aug 3 2016, 18:12:10) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import foo 
>>> foo.bar 
'from the foo module' 
>>> from foo import bar 
>>> bar 
'from the foo module' 
>>> import foo.bar as bar 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named bar 

注意をインポートが成功したすべてのケースでは、あなたが何かにバインドされたグローバル名barで終わること、モジュールのオブジェクト、またはモジュールオブジェクト。

5

バーがモジュールでない場合には、大きな違いがあります:

# foo.py 
bar = object() 

ここfrom foo import barはpythonで正常であるだろうが、import foo.bar as barImportError: No module named barを引き上げます。

通常、わかりやすさを高めるために名前にコンテキストを追加するため、または別の名前との衝突を避けるために、名前を別名にするために "as"構造体のみを使用します。

関連する問題