2017-01-13 4 views
1

問題のビット背景。 Python2.7でコードを書いていますが、うまくいきます。しかし私は使いやすさとメンテナンスの目的でこれをモジュールに分解することにしました。私はヒットとトライアルの方法で動作させることはできましたが、正しいアプローチかどうかは分かりませんが、ここで共有しています。ここで共有されるコードは、同じロジック、順序、およびアプローチを推進する実際のコードの単純化された複製です。Python2.7でメインスクリプトや他のユーザ定義関数から変数を使用する方法

MainEx.pyも内部

from LogIn_1 import LogIn 
global NumTry 
NumTry = 2 
LogIn() 
# xx is here just to show NumTry variable is further used in MainEx script 
xx = NumTry*3 

基本的に私はここで通信しようとNumTry変数がMainEx.py(最高レベルのスクリプト)で使用されているもの、最も高いレベルで実行中のスクリプトとありますLogIn()関数。また、私が作成している他の関数でも使用されます。

LogIn_1.pyは、ユーザー定義関数

MainEx.pyを実行
def LogIn(): 
    from MainEx import NumTry 
    # following are some computations involving NumTry 
    print NumTry 

は結果を与えている:

2 
2 

質問:なぜそれが二回 2.結果を生成している 1.わからないがMainExをインポートしているLogIn_1とLogIn_1をインポートすると奇妙に思える。お互いに変数をインポートするピンポンの種類。

は、私は次のように変更して右の成果にできる午前:

2 

I: MainEx.py

from LogIn_1 import LogIn 
global NumTry 
NumTry = 2 
#LogIn() 
# xx is here just to show NumTry variable is further used in MainEx script 
xx = NumTry*3 

LogIn_1.py

def LogIn(): 
    from MainEx import NumTry 
    # following are some computations involving NumTry 
    print NumTry 
LogIn() 

MainEx.pyを実行すると、結果を提供します将来の問題を回避するためのベストプラクティスを理解しようとしています。

答えて

1

あなたのコードにprint文の束を追加する場合は、血みどろの詳細に従うことができます:

# MainEx.py 
print 'MainEx: start' 
from LogIn_1 import LogIn 
print 'MainEx: after Login import' 
global NumTry 
NumTry = 2 
print 'MainEx: before Login() call' 
LogIn() 
print 'MainEx: after Login() call' 
xx = NumTry*3 
print 'MainEx: finish' 

# LogIn_1.py 
print 'start LogIn_1' 
def LogIn(): 
    print ' Login(): start' 
    from MainEx import NumTry 
    print ' Login(): after MainEx import' 
    print NumTry 
    print ' Login(): finish' 
print 'finish LogIn_1' 

出力:

MainEx: start 
start LogIn_1 
finish LogIn_1 
MainEx: after Login import 
MainEx: before Login() call 
    Login(): start 
MainEx: start      # Code in MainEx running again! 
MainEx: after Login import 
MainEx: before Login() call 
    Login(): start 
    Login(): after MainEx import 
2 
    Login(): finish 
MainEx: after Login() call 
MainEx: finish 
    Login(): after MainEx import 
2 
    Login(): finish 
MainEx: after Login() call 
MainEx: finish 

あなたが見ることができるように、(a)は円形の輸入を組み合わせます(b)最上位の副作用を有するコードは、不都合な結果をもたらす。特に、from MainEx import NumTryLogin()呼び出しで実行されている場合、そのモジュールにはNumTry属性がまだないため、PythonはMainExのコードを再実行する必要があり、二重印刷につながっているようです。私はこの結果を本当に期待していませんでしたが、そこにはあります。

ベストプラクティス提案:

  • あなたのモジュールの上部にあなたのimport文ではなく、内部関数やクラスを入れてください。

  • 循環インポートを回避するようにコードを設計します。あなたのプログラムのモジュールは、一種の階層を持ちます。あなたの低レベルのモジュールはあなた自身のコードベースから何もインポートしません。あなたのより高いレベルのモジュールはあなたのより低いレベルのモジュールをインポートします。

  • がトップレベルで発生しないように、モジュールを設計してください。モジュールは、クラスを定義したり、関数を定義したり、定数を代入したり、下位モジュールをインポートしたりするだけです。お使いのシステムの唯一の主要なモジュールに何かを行う必要があります - そしてその何かが(任意のコマンドライン引数に渡して)あなたのトップレベルの機能を呼び出すために、ここでスケッチとしても、その呼び出しは、条件付きでなければなりませんようになります。

    import sys 
    
    def main(args): 
        ... 
    
    def foo(): 
        ... 
    
    def bar(): 
        ... 
    
    if __name__ == '__main__': 
        main(sys.argv[1:]) 
    
+0

@FMcに感謝しますが、私は1つの大きなプログラムに戻ってきましたが、これは有用であり、モジュールアプローチを学び続けるでしょう – Abacus

関連する問題