[解決済み] Python: サブパッケージやサブモジュールのインポート
質問
フラットパッケージをすでに使っていたので、ネストされたパッケージで遭遇した問題は予想外でした。これは...
ディレクトリのレイアウト
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
の内容 init .py
どちらも
package/__init__.py
と
package/subpackage/__init__.py
は空です。
の内容
module.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
の内容
test.py
(3つのバージョン)
バージョン1
# file test.py
from package.subpackage.module import *
print attribute1 # OK
これはインポートする際の悪い安全でない方法(一括してインポートする)ですが、動作はします。
バージョン 2
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
項目ごとにインポートする安全な方法ですが、Pythonはこれを望んでいません: "モジュールという名前のモジュールがありません"というメッセージで失敗します。しかし ...
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here
...は言う
<module 'package.subpackage.module' from '...'>
. だから、それはモジュールだが、それはモジュールではない /-P 8-O ...ええと。
バージョン 3
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK
こちらは動作します。つまり、常に過剰なプレフィックスを使わざるを得ないか、バージョン#1のような安全でない方法を使い、安全で便利な方法を使うことはPythonに拒否されるということですか?安全で不必要な長いプレフィックスを避けるより良い方法は、Pythonが拒否する唯一の方法なのでしょうか?これは
import *
が好きだからなのか、それとも長い接頭辞が好きだからなのか(これはこの慣習を強制するのに役立ちません)?
難しい言葉で申し訳ありませんが、この愚かなような動作を回避するために2日間試行錯誤しています。私がどこかで完全に間違っていない限り、これは、Python のパッケージとサブパッケージのモデルで何かが本当に壊れているような気がしています。
ノート
-
に頼りたくない。
sys.path
には頼りたくないし、グローバルな副作用を避けるために*.pth
ファイルでもありません。sys.path
を同じグローバルな効果で再生する別の方法です。解決策がクリーンであるためには、それはローカルでなければなりません。Pythonはサブパッケージを扱うことができ、そうでないこともありますが、ローカルなものを扱えるようにするためにグローバルな設定を弄る必要はないはずです。 -
でimportを使うことも試してみました。
package/subpackage/__init__.py
でも、それは何も解決しません、それは同じことをして、文句を言うsubpackage
は既知のモジュールではないのにprint subpackage
はそれがモジュールであると言っています (奇妙な動作です、もう一度)。
私が完全に間違っているのかもしれませんが(私が望む選択肢)、これはPythonについて多くの失望を感じさせてくれます。
私が試した3つの方法の他に既知の方法はありますか?私が知らない何か?
(ため息)
----- %< ----- 編集 ----- >% -----
ここまでの結論(みんなのコメントを受けて)
Pythonには本当のサブパッケージのようなものはありません。すべてのパッケージの参照はグローバルな辞書にのみ送られ、ローカルな辞書は存在しません。
完全なプレフィックスか短いプレフィックス、またはエイリアスを使う必要があります。というように。
フルプレフィックス版
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
短い接頭辞版(ただし接頭辞の繰り返し)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place
さもなくば、上記のバリエーション。
from package.subpackage import module as m
use_of (m.attribute1)
# `m` is a shorter prefix, but you could as well
# define a more meaningful name after the context
因数分解バージョン
複数のエンティティを一括でインポートすることにこだわらなければ、可能です。
from package.subpackage.module import attribute1, attribute2
# and etc.
私の最初の好みのテイストではありませんが(私はインポートされたエンティティごとに1つのインポート文を持つことを好みます)、私が個人的に好むであろうものであるかもしれません。
更新 (2012-09-14)。
最後にレイアウトについてのコメントを除いて、実際には問題ないようです。上記の代わりに、私は使用しました。
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.
どのように解決するのですか?
あなたは、以下の方法を誤解しているようです。
import
がモジュールを検索する方法を誤解しているようです。 import ステートメントを使用すると
常に
は実際のモジュールのパスを検索します (そして
sys.modules
を使用しません。
オブジェクト
を利用しません。 そうすると
import package.subpackage.module
from package.subpackage import module
from module import attribute1
2行目は
package.subpackage
というパッケージを探し、インポートします。
module
をそのパッケージから削除します。 この行は3行目には何の影響も及ぼしません。 3 行目は、単に
module
というモジュールを探すだけで、それが見つかりません。 というオブジェクトを再利用するわけではありません。
module
というオブジェクトを再利用しません。
言い換えると
from someModule import ...
は "以前にインポートした someModule というモジュールから... " という意味ではなく、 sys.path で見つけた someModule という名前のモジュールから... " という意味なんですね。 モジュールにつながるパッケージをインポートすることによって、モジュールのパスを "インクリメンタル"に構築する方法はありません。 インポートする際には常にモジュール名全体を参照する必要があります。
何を達成しようとしているのか明確ではありません。 もしあなたが特定のオブジェクトattribute1だけをインポートしたいのであれば、単に
from package.subpackage.module import attribute1
として、それで終わりです。 長い
package.subpackage.module
から欲しい名前をインポートしてしまえば、長い
もし、あなたが
する
が、後で他の名前にアクセスするためにモジュールにアクセスできるようにしたい場合は
from package.subpackage import module
で、見ての通り、その後に
module.attribute1
といった具合に、好きなだけ繰り返すことができます。
もし、あなたが
ともに
--- が必要な場合、つまり
attribute1
に直接アクセスできる
と
にアクセスしたい場合は
module
にアクセスしたい場合は、上記の両方を実行するだけです。
from package.subpackage import module
from package.subpackage.module import attribute1
attribute1 # works
module.someOtherAttribute # also works
と入力するのが嫌な場合は
package.subpackage
を二度打つのが嫌なら、attribute1へのローカル参照を手動で作ればいいのです。
from package.subpackage import module
attribute1 = module.attribute1
attribute1 # works
module.someOtherAttribute #also works
関連
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] インストールされているnpmパッケージのバージョンを検索する
-
[解決済み] 億の相対的輸入
-
[解決済み] PythonモジュールとPythonパッケージの違いは何ですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] 2つの線分が交差しているかどうかを確認するにはどうすればよいですか?
-
[解決済み] 辞書のキーと値を交換するにはどうすればよいですか?
-
[解決済み] Django で全てのリクエストヘッダを取得するにはどうすれば良いですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Jupyterノートブックでenv変数を設定する方法
-
[解決済み] PythonでファイルのMD5チェックサムを計算するには?重複
-
[解決済み] PythonでSVGからPNGに変換する
-
[解決済み] Python 3でバイナリデータを標準出力に書き込むには?
-
[解決済み] python-requests モジュールからのすべてのリクエストをログに記録します。
-
[解決済み] サブフォルダからのインポートモジュール
-
[解決済み] あるオブジェクトが数であるかどうかを確認する、最もパイソン的な方法は何でしょうか?
-
[解決済み] PySparkでデータフレームのカラムをString型からDouble型に変更する方法は?
-
[解決済み] あるメソッドが複数の引数のうち1つの引数で呼び出されたことを保証する
-
[解決済み] Pythonの辞書にあるスレッドセーフについて