私がしている答えた私は、私が読んで理解に基づいて考えPythonで絶対的な輸入に関するご質問、Pythonの2.5変更履歴をとそれに付随するPEPを。ただし、Python 2.5をインストールしfrom __future__ import absolute_import
、を適切に使用する例を作成しようとしたところ、状況がそれほど明確ではないことに気付きました。
上記のリンクされた変更ログから直接、このステートメントは、絶対的なインポートの変更に関する私の理解を正確に要約したものです。
次のようなパッケージディレクトリがあるとします。
pkg/ pkg/__init__.py pkg/main.py pkg/string.py
これはおよびサブモジュール
pkg
を含むという名前のパッケージを定義します。pkg.main
pkg.string
main.pyモジュールのコードを検討してください。ステートメントを実行するとどうなり
import string
ますか?Python 2.4以前では、最初にパッケージのディレクトリを参照して相対インポートを実行し、pkg / string.pyを見つけて、そのファイルの内容をpkg.string
モジュールとしてインポートします。"string"
そのpkg.main
モジュールは、モジュールの名前空間の名前にバインドされます。
だから私はこの正確なディレクトリ構造を作成しました:
$ ls -R
.:
pkg/
./pkg:
__init__.py main.py string.py
__init__.py
とstring.py
空です。main.py
次のコードが含まれています。
import string
print string.ascii_uppercase
予想通り、Python 2.5でこれを実行すると、AttributeError
:
$ python2.5 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
ただし、2.5の変更ログにさらに沿って、次のことがわかります(強調が追加されています)。
Python 2.5では
import
、from __future__ import absolute_import
ディレクティブを使用しての動作を絶対インポートに切り替えることができます。この絶対インポートの動作は、将来のバージョン(おそらくPython 2.7)でデフォルトになる予定です。絶対インポートがデフォルトにimport string
なると、は常に標準ライブラリのバージョンを見つけます。
このようにしてpkg/main2.py
、と同じですmain.py
が、追加のfutureインポートディレクティブを作成しました。これは次のようになります。
from __future__ import absolute_import
import string
print string.ascii_uppercase
ただし、これをPython 2.5で実行すると、...で失敗しますAttributeError
。
$ python2.5 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
これはかなりきっぱりと声明と矛盾import string
します常に絶対的な輸入を有効にしてSTD-libのバージョンを確認します。さらに、絶対インポートが「新しいデフォルト」の動作になるようにスケジュールされているという警告にもかかわらず、私は__future__
ディレクティブの有無にかかわらず、Python 2.7の両方を使用してこの同じ問題に遭遇しました。
$ python2.7 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
$ python2.7 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
Python 3.5と同様に、またはなし(print
ステートメントが両方のファイルで変更されていると想定):
$ python3.5 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'
$ python3.5 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'
これの他のバリエーションをテストしました。代わりのstring.py
名前のディレクトリ- 、私は空のモジュールを作成しているstring
だけで、空含んを__init__.py
- 、代わりにからの輸入を発行するmain.py
、私が持っているcd
「とdはpkg
とREPLから直接輸入を実行します。これらのバリエーション(またはそれらの組み合わせ)のいずれも、上記の結果を変更しませんでした。__future__
ディレクティブと絶対インポートについて読んだ内容とは一致しません。
これは次のように簡単に説明できるようです(これはPython 2ドキュメントからのものですが、このステートメントはPython 3の同じドキュメントでも変更されていません)。
sys.path
(...)
プログラムの起動時に初期化されると、このリストの最初の項目は
path[0]
、Pythonインタープリターを呼び出すために使用されたスクリプトを含むディレクトリです。スクリプトディレクトリが利用できない場合(たとえば、インタプリタがインタラクティブに呼び出される場合、またはスクリプトが標準入力から読み取られる場合)path[0]
は、空の文字列で、Pythonに現在のディレクトリでモジュールを最初に検索するように指示します。
それで私は何が欠けていますか?どうして__future__
ステートメントは言っているように見えないのですか?また、ドキュメントのこれら2つのセクション間、および説明された動作と実際の動作の間のこの矛盾の解決策は何ですか?