2

私は現在 Python で作業しており、関数が にリストされているという事実について混乱しています__main__。私は複数の python スクリプトを調べて、どの関数が の場所を保証するかについて共通のテーマを見つけようとしました__main__が、役に立ちませんでした。ここに私自身のコードのサンプルがあります。firstfunctionanotherfunction私のコードで唯一の 2 つの関数です。

def main(argv):

    firstinput=""
    secondinput=""

    if len(argv) < 3 or len(argv) > 3:
        print """"Please set to:
                metisfinal.main(metisfinal.py, firstinput, secondinput)""""
        return
    else:
        firstinput = argv[1]
        secondinput = argv[2]

    firstfunction(firstinput, dictionary)
    anotherfunction(list, secondinput)

if __name__ == "__main__":
    main(sys.argv)

(私は思う)引数と__main__呼び出しが正しいことを知っていますが firstfunctionanotherfunction常にエラーを返します(引数がグローバルに定義されていないため)。私が見た他のすべての例は、基本的に同じ方法で__main__設定されているため、これは の誤った理解から生じていると確信しています。__main__

に特定の関数をリストすることを構成するものは何__main__ですか? 30 以上の関数を含む Python コードをいくつか見つけましたが、プログラマーはそれらの関数のうちの 2 つだけを__main__. 同様に、次のように、コードのメイン引数にクラスが含まれることがあります (Projectは以前にオブジェクト クラスとして定義されていました)。

def main(argv):

    filename = ""
    outputfilename = ""

    p = Project(filename, outputfilename, subdomainNames) 
    p.generateICs()

if __name__ == "__main__":
    main(sys.argv)

概念的には、なぜすべての関数がリストされていないのか理解できません...それらのすべてを実行する必要はありませんか、__main__それとも単に何かを初期化していますか?

非定型コードを見ていますか? __main__欠けている重要な概念は何ですか? そして、どの関数を に入れるかを見つけたら__main__、それらをフォーマットする特定の方法はありますか?

4

2 に答える 2

8

「にリストされている」とはどういう意味か明確ではありません__main____main__はソース ファイル内のエンティティではありません。むしろ、直接実行する場合はモジュールの名前です。を実行するif __name__=="__main__"と、コードがメイン モジュールとして実行されている場合 (つまり、プログラムが実行されている場合) にのみ、そのブロック内のコードを実行するよう Python に指示されます。if __name__=="__main__"モジュールが別のモジュールからインポートされた場合、ブロック内のコードは実行されません。

そのifブロックでは関数を「リスト」しないことに注意してください。代わりに、実行するブロックに通常のプログラム コードを配置します。多くの場合、このコードは 1 つの関数を呼び出すだけです。多くの場合、人々はその関数を と呼びますmain()__main__しかし、 と の間に特別な関係はありませんmain。関数は好きなように呼び出すことができます:

def snicklefritz():
    # This function will be run when you run the program
    print "You ran the program!"

if __name__ == "__main__":
    snicklefritz()

このプログラムを実行してみてください (たとえば、「snicklefritz.py」として保存しpython snicklefritz.py、コマンド ラインから実行します)。「プログラムを実行しました!」と表示されます。印刷されます。代わりに別のファイルを作成するとimport snicklefritz、メッセージは出力されません。

「関数のリスト」については何もないことに注意してください。たとえば、次のプログラムを見てください。

print "This will always be printed!"

if __name__ == "__main__":
    print "This will only be printed if you run the file as a program!"

ここで、if __name__=="__main__"ブロックは関数を「リスト」しません。ファイルがスクリプトとして実行されたときに実行される実際のコードが含まれているだけです。ただし、関数の外に「公開」するだけでなく、別の関数にコードを配置する方が整然としているため、通常はこれを行いません。

他の関数については、モジュール内で使用するか、モジュールをインポートする他のモジュールで使用するために、モジュール内で好きな他の関数を定義できます。通常、モジュール内のほとんどの関数はif __name__=="__main__"、「メイン」関数の一部ではないため、ブロック内では使用されません。代わりに、他のコードで使用するための他の関数になります。例えば:

def otherFunc(x):
    # Return x squared
    return x**2

def snicklefritz():
    # This function will be run when you run the program
    print "You ran the program!"

if __name__ == "__main__":
    snicklefritz()

otherFuncモジュールではまったく使用されません。それはいいです。誰かがあなたのモジュールをインポートしてotherFunc自分自身を使いたがるかもしれません。if __name__=="__main__"すべての関数を同じモジュール内で使用する必要はなく、ブロックから呼び出す必要はありません。

于 2012-06-29T19:27:25.110 に答える
3

__main__あなたはイディオムを誤解しています。

というファイルに保存された以下のプログラムを考えてみましょうsum.py

def read_numbers():
    n1 = int(raw_input())
    n2 = int(raw_input())
    return n1, n2

def sum_numbers(i1, i2):
    return i1+i2

def print_sum(i1, i2, i3):
    print "%d + %d = %d" % (i1, i2, i3)

v1, v2 = read_numbers()
sum = sum_numbers(v1, v2)
print_sum(v1, v2, sum)

これには 3 つの関数があります。1 つは標準入力から 2 つの数値を読み取り、もう 1 つはそれらを合計し、3 番目は演算を出力します。関数を定義した後、2 つの数値を読み取ってその合計を出力するように関数を呼び出します。かなり簡単です。実行すると、次のような結果が得られます。

$ python sum.py 
12
34
12 + 34 = 46

ここで、1 つの数値のみを読み取る別のプログラムを作成する必要があるとします。もう 1 つの数値は実際に指定されています。私はすでにsum_numbers()関数と関数を持っているのでprint_sum()、モジュールを再利用したくなることがありsumます。これは良いことです:

import sum
MY_FIXED_NUMBER=3
n = int(raw_input())
value = sum.sum_numbers(n, MY_FIXED_NUMBER)
print_sum(n, MY_FIXED_NUMBER, value)

すごい!しかし、それを実行すると、何が得られますか? これ:

$ python three_sum.py 
12
34
12 + 34 = 46
12
12 + 3 = 15

なに?! プログラムは私に 2 つの数を要求し、それらの合計を出力し、次に 3 番目の数を要求しましたが、これは正しく合計されて 3 になりました。どうしたの?

モジュール ( などimport sum) をインポートすると、その中のすべてのコードが実行されることがありました。したがって、私のモジュールには 2 つの部分があります。1 つは他の場所で使用できる便利な関数を定義する部分 (定義部分と呼びます) と、特定の結果を得るためにこの関数を実行する部分です。プログラムとしてのモジュール (これを実行部分と呼びます)。実行部分は常に実行されます。

幸いなことに、Python には、モジュールがインポートされていない場合にのみ実行部分を実行できるようにするトリックがあります。を使用して Python ファイルをインポートするとimport、モジュールには という変数があり__name__、その名前はモジュールの元の名前になります。

>>> import sum
12
34
12 + 34 = 46
>>> sum.__name__
'sum'

ただし、Python ファイルをスクリプトとして実行すると ( $ python sum.py)、__name__変数は存在しますが、名前が異なります。次のような行を追加するとします。

print __name__

私の最後にsum.py。もう一度実行すると、次のようになりました。

$ python sum.py
12
34
12 + 34 = 46
__main__

一方、 を実行するthree_sum.pyと、 の結果print __name__は大きく異なります。

$ python three_sum.py 
12
34
12 + 34 = 46
sum
12
12 + 3 = 15

はい、__name__ファイルをスクリプトとして実行するときの変数の値は です__main__

それで、これはどのように私を助けることができますか?このように: モジュールの実行部分をif条件内に配置します。モジュールの名前が の場合は__main__、ファイルがスクリプトとして実行されているためです$ python sum.py。この場合、モジュールの実行部分を実行する必要があります。したがって、私のsum.pyモジュールは次のようになります。

def read_numbers():
    n1 = int(raw_input())
    n2 = int(raw_input())
    return n1, n2

def sum_numbers(i1, i2):
    return i1+i2

def print_sum(i1, i2, i3):
    print "%d + %d = %d" % (i1, i2, i3)

if __name__ == "__main__":
    v1, v2 = read_numbers()
    sum = sum_numbers(v1, v2)
    print_sum(v1, v2, sum)

を実行$ python sum.pyすると、以前と同じ結果が得られます。

$ python sum.py
12
34
12 + 34 = 46

ただし、 を実行するthree_sum.pyと、すべてが異なります。

$ python three_sum.py 
12
12 + 3 = 15

これで期待どおりに動作します。最初の実行でのモジュールの名前が であるため、このように動作し、__main__その下のコマンドif __name__ == "__main__" が実行されます。ただし、2 回目の実行では、モジュールの名前がsumであるため、 の下のコマンドifは実行されません。

ファイルがインポートされるように設計されていない場合でも、ファイルの実行部分を の下if __name__ == "__main__"に配置することをお勧めします。これにより、ファイルを簡単にモジュールに適合させることができます。

于 2012-06-29T19:59:14.723 に答える