8

main.py:

    import package

パッケージ/__init__.py:

    # use function to split local and global namespace
    def do_import():
        print globals().keys()
        print locals().keys()

        import foo as mod

        print locals().keys()
        print globals().keys()

    do_import()

パッケージ/foo.py:

    print 'Hello from foo'

main.py を実行すると、次のように出力されます。

['__builtins__', '__file__', '__package__', '__path__', '__name__', 'do_import', '__doc__']
[]
Hello from foo
['mod']
['__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', 'do_import', '__doc__']

importイン__init__.pyは期待どおりに機能しませんでした。グローバル名前空間には、ローカルの「mod」のみにバインドする必要がある「foo」があることに注意してください

exec "import foo as mod" in {'__name__': __name__, '__path__': __path__} グローバル名前空間の変更を止めることはできません

これはどのように起こりますか?

4

1 に答える 1

4

ああ!むずかしいけど、わかった!

「foo」は単純な「他のパッケージ」ではありません。Python では、「パッケージ」モジュールのサブモジュールのように見えます。

初めて「パッケージ」を実行すると、外部スクリプトからインポートするか、-mコマンド ライン スイッチを使用して実行します (ただしpython package/__init__.py、コマンド ラインから直接実行する場合は除きます)。「パッケージ」モジュールが解析され、sys.modules辞書 (sysモジュール上)。

サブモジュールfooが読み込まれるとsys.modules、 key の直下に配置される["package.foo"]だけでなく、その親モジュールへの属性としても設定されます。したがって、Python アプリで として利用できますpackage.foo。で属性を設定すると、実行時にグローバルでsys.modules["package"]キーを設定するのと同じ効果があります。package/__init__.pyそれが起こっていることです。

プロセスを適切に言葉に翻訳できれば幸いです。そうでない場合は、コメントでもう一度質問してください。

-- これはおそらくあなたが持っている実際のコードで起こっており、「do_import」に相当するものがパッケージの外側のコードから呼び出されているため (そして、サブモジュールをパッケージのグローバル名前空間に表示させるという副作用があります)、あなたがやっている方法で簡単に回避することはできません。私の提案は_、サブモジュール名がパッケージ外の一般的なコードから呼び出されることを意図していない場合、サブモジュール名の先頭にアンダースコア ( ) を追加することです。(この場合、誰かが表示しても表示されませんfrom package import *

于 2012-09-24T04:05:13.570 に答える