[解決済み] Pythonの__import__はなぜfromlistを要求するのですか?
質問
Pythonでは、プログラム的にモジュールをインポートしたい場合、以下のようにします。
module = __import__('module_name')
サブモジュールをインポートしたい場合、単純に考えると
module = __import__('module_name.submodule')
もちろん、これはうまくいきません。
module_name
になってしまいます。そうしなければなりません。
module = __import__('module_name.submodule', fromlist=['blah'])
なぜですか?
の実際の値は
fromlist
の実際の値は、それが空でない限り、全く問題ではないようです。引数を要求しておいて、その値を無視することに何の意味があるのでしょうか?
Pythonのほとんどのものは正当な理由のために行われるようですが、どうしても、この動作が存在するための合理的な説明を思いつくことができません。
どのように解決するのですか?
実は
__import__()
の実装に起因しています。
import
ステートメントを呼び出すからです。
__import__()
. 基本的に、5つの微妙に異なる方法があります。
__import__()
が呼び出すことができるのは
import
(2つの主要なカテゴリを持つ)。
import pkg
import pkg.mod
from pkg import mod, mod2
from pkg.mod import func, func2
from pkg.mod import submod
最初の
と
の場合は
import
ステートメントは "left-most" モジュールオブジェクトを "left-most" の名前に割り当てる必要があります。
pkg
. その後
import pkg.mod
の後に
pkg.mod.func()
なぜなら
import
ステートメントがローカル名
pkg
というモジュールオブジェクトがあり、これは
mod
属性があります。そのため
__import__()
関数が一番左のモジュールオブジェクトを返さなければならないので、それを
pkg
. これらの2つのimport文は、このように変換されます。
pkg = __import__('pkg')
pkg = __import__('pkg.mod')
3番目、4番目、5番目の場合は
import
文はより多くの仕事をしなければなりません。それは、モジュール・オブジェクトから取得しなければならない(潜在的に)複数の名前に割り当てなければなりません。そのため
__import__()
関数は1つのオブジェクトしか返せないので、モジュールオブジェクトからそれぞれの名前を取得させる本当の理由はありません(そして、それは実装をより複雑にするでしょう)。 だから、単純なアプローチは次のようになります(3番目のケースについて)。
tmp = __import__('pkg')
mod = tmp.mod
mod2 = tmp.mod2
しかし、この場合
pkg
がパッケージで
mod
または
mod2
はそのパッケージのモジュール
で、まだインポートされていない
であり、3番目と5番目のケースと同様です。は、その
__import__()
関数が知る必要があるのは
mod
と
mod2
という名前は
import
文がアクセスできるようにしたい名前です。そうすることで、それらがモジュールであるかどうかを確認し、それらもインポートしようとします。ですから、呼び出しはより近いものになります。
tmp = __import__('pkg', fromlist=['mod', 'mod2'])
mod = tmp.mod
mod2 = tmp.mod2
というのは
__import__()
を読み込もうとすると
pkg.mod
と
pkg.mod2
と同様に
pkg
(を使用することができます(ただし、もし
mod
または
mod2
が存在しない場合は、エラーではなく
__import__()
呼び出しのエラーではありません。エラーの発生は
import
ステートメントに任されています)。しかし、それはまだ4番目と5番目の例にとって正しいことではありません。なぜなら、もし呼び出しがそうであったなら。
tmp = __import__('pkg.mod', fromlist=['submod'])
submod = tmp.submod
では
tmp
は結局のところ
pkg
になってしまい、以前のように
pkg.mod
モジュールを取得したい場合は
submod
属性を取得することができます。実装では、このように
import
文が余計な仕事をするようにし、パッケージ名を
.
のように
__import__()
関数がすでに行っているような、名前のトラバースを行いますが、これでは労力の一部が重複してしまうことになります。そこで、代わりに、実装では
__import__()
を返すようにしました。
一番右の
モジュールの代わりに
の代わりに
という
場合のみ
fromlistが渡され、空でない場合のみ。
(その
import pkg as p
と
from pkg import mod as m
の構文は、どのローカル名に割り当てられるかを除いて、この話については何も変わりません。
__import__()
関数は
as
が使用されている場合、すべて
import
文の実装のままです)。
関連
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み] Pythonでシングルトンを作成する
-
[解決済み] Pythonのsuper()は多重継承でどう動くのか?
-
[解決済み] モジュール名を文字列で指定してインポートするには?
-
[解決済み】if __name__ == "__main__": は何をするのでしょうか?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] 古いバージョンのPythonにおける辞書のキーの並び順
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Pandasのデータフレームでタプルの列を分割するにはどうしたらいいですか?
-
[解決済み] Pythonのマルチプロセッシングプールimap_unorderedの呼び出しの進捗を表示しますか?
-
[解決済み] Pythonです。未束縛のメソッドを束縛する?
-
[解決済み] pandasのDataFrameから空のセルを含む行を削除する
-
[解決済み] バブルソートの宿題
-
[解決済み] dict を txt ファイルに書き、それを読み取る?
-
[解決済み] SQLAlchemy: 日付フィールドをフィルタリングする方法は?
-
[解決済み] python-requests モジュールからのすべてのリクエストをログに記録します。
-
[解決済み] Jupyter (IPython)ノートブックのセッションをpickleして保存する方法
-
[解決済み] Pythonの検索パスを他のソースに展開する