Pythonでの絶対インポートに関する質問に from __future__ import Absolute_import
を適切に使用する例を作成しようとすると、状況がそれほど明確ではないことがわかります。
上記のリンク先の変更ログから直接、これステートメントは、絶対インポートの変更についての私の理解を正確に要約しています。
次のようなパッケージディレクトリがあるとします:
pkg / pkg / __init__。py pkg / main.py pkg / string.py
これは、
pkg.main
とを含む
サブモジュール。pkg
という名前のパッケージを定義します。 pkg.stringmain.pyモジュールのコードを検討してください。ステートメント
importstring
を実行するとどうなりますか?Python 2.4以前では、最初にパッケージのディレクトリを調べて相対インポートを実行し、pkg / string.pyを見つけ、そのファイルの内容をpkg.string
モジュールとしてインポートし、そのモジュールは名前にバインドされますpkg.main
モジュールの名前の"string"
ペース。
この正確なディレクトリ構造を作成しました:
$ ls -R。:pkg / ./pkg:__init__。pymain.py string .py
__init__。py
とstring.py
は空です。 main.py
には次のコードが含まれています。
import string print string.ascii_uppercase
予想どおり、これをPython2.5で実行します。 AttributeError
で失敗します:
$ python2.5 pkg / main.pyトレースバック(最後の最後の呼び出し):ファイル "pkg / main.py"、2行目、< module> print string.ascii_uppercase AttributeError:"module"オブジェクトには属性"ascii_uppercase"がありません
ただし、2.5の変更ログでは、次のことがわかります(強調が追加されています):
Python 2.5では、
from __future__ import Absolute_import
ディレクティブを使用して、import
の動作を絶対インポートに切り替えることができます。このabsolute-import動作はのデフォルトになります。将来のバージョン(おそらくPython 2.7)。絶対インポートがデフォルトになると、import string
は常に標準ライブラリのバージョンを検索します。
このようにして、 main.py
と同じpkg/ main2.py
を作成しましたが、将来のインポートディレクティブが追加されています。これで、次のようになります。
from __future__ import Absolute_import import string print string.ascii_uppercase
Python 2.5でこれを実行すると、...が失敗します。 AttributeError
:
$ python2.5 pkg / main2.pyトレースバック(最後の最後の呼び出し):ファイル "pkg / main2.py"、3行目&lt ;モジュール> print string.ascii_uppercase AttributeError:"module"オブジェクトには属性"ascii_uppercase"がありません
これは、 import string
が常に絶対インポートが有効になっているstd-libバージョンを検索します。さらに、絶対インポートが「新しいデフォルト」の動作になるようにスケジュールされているという警告にもかかわらず、 __ future __
ディレクティブの有無にかかわらずPython2.7の両方を使用して同じ問題が発生しました:
$ python2.7 pkg / main.pyトレースバック(最後の最後の呼び出し):ファイル "pkg / main.py"、2行目、< module> print string.ascii_uppercase AttributeError:"module"オブジェクト属性「ascii_uppercase」がありません$python2.7pkg / main2.pyトレースバック(最後の最後の呼び出し):ファイル「pkg / main2.py」、3行目、< module> print string.ascii_uppercase AttributeError:「module」オブジェクト属性「ascii_uppercase」
とPython3.5はありません(両方のファイルで print
ステートメントが変更されていると仮定します):
$ python3.5 pkg / main.pyトレースバック(最後の最後の呼び出し):ファイル "pkg / main.py"、2行目< module> print(string.ascii_uppercase)AttributeError:module "string "には属性"ascii_uppercase"がありません$python3.5pkg / main2.py Trac eback(最後の最後の呼び出し):< module>のファイル "pkg / main2.py"、3行目print(string.ascii_uppercase)AttributeError:モジュール"string"には属性"ascii_uppercase"がありません
これの他のバリエーションをテストしました。 string.py
の代わりに、空のモジュール( __init__。py
のみを含むstring
という名前のディレクトリ)を作成しました。代わりに main.py
からインポートを発行する場合、 cd
"dをpkg
に設定し、REPLから直接インポートを実行します。これらのバリエーション(またはそれらの組み合わせ)上記の結果を変更しました。これを、 __ future __
ディレクティブおよび絶対インポートについて読んだ内容と一致させることはできません。
これは簡単に説明できるようです。 次の(これはPython 2のドキュメントからのものですが、これはPython 3)の同じドキュメントでは、ステートメントは変更されていません。
sys.path
(...)
プログラムの起動時に初期化されるため、このリストの最初の項目である
path[0]
は、Pythonインタープリターを呼び出すために使用されたスクリプトを含むディレクトリです。スクリプトディレクターの場合yは使用できません(たとえば、インタプリタがインタラクティブに呼び出される場合、またはスクリプトが標準入力から読み取られる場合)、path [0]
は空の文字列であり、Pythonに現在のディレクトリが最初です。
では、何が欠けているのでしょうか。 __ future __
ステートメントが、その内容を実行していないように見えるのはなぜですか。また、ドキュメントのこれら2つのセクション間、および説明された動作と実際の動作の間のこの矛盾の解決策は何ですか?