-3

私はよくいくつかのコードを見ます

def main(A,B)
    some steps

「メイン関数のオーバーロード」として説明されていますが、Pythonについてより具体的なことを読んだ後、これは正しくないことがわかりました。理由は次のとおりです。

  • Pythonはロスレスタイプの言語です
  • Pythonの関数/メソッドは、特定のパラメーターの型さえ知らず、Pythonは気にしません

インスタンスと「静的メソッド」または「クラスメソッド」の間に実際の違いがあるかどうかもわかりません。おそらくそれらは同じものであり、唯一の違いはデコラトの使用によって与えられますが、これはおそらく私のものに関連していますC / C ++で多くの時間を費やした後の、関数型言語への最初のアプローチ。

さらに、Pythonでは、最初のインデントレベルがエントリポイントとして使用されるため(C / C ++のmain()のように)、実際の最初のインデントレベルとは異なるインデントレベルでメインを定義する必要がある理由がわかりません。 1。

Pythonのキーワードについて私が持っている一般的な考え方は、キーワードは実際に定義された構文ではなく、特別な意味値を持っているということです(おそらく、C ++は「慣用的」ではないため、それをどのように説明するかはわかりません)、使用されます何かのプレースホルダーとして、それらが適用されるセクションに特別な意味を与えます。そのような特別な変数もあり、特別__name__な情報を保存するためだけにあり、それ以上のものはありません。

私の脳に保存されているこの小さな情報のすべての後、私はまだ最初のコード例の本当の意味を理解していません:

  • main()関数の何が特別なのですか?
  • それが本当の「メイン」でない場合、「メイン」関数のようなものを定義することのポイントは何ですか
  • 入力されていない場合に呼び出す関数をPythonがどのように決定するのですか?
  • __init__.pyインタプリタがファイルを読み取る方法と他のファイルを読み取る方法に違いはありますか?
4

2 に答える 2

1

あなたの質問に答えるには:

main()働き

特別なことは何もありません。次のようなことをして、自分で呼び出す必要があります。

def main():
    print "This is main"

if __name__ == "__main__":
    main()

使用する理由main()

これを行う理由は、メインのエントリポイントコードを便利な方法でまとめるためです。たとえば、でいくつかの変数を作成した場合main()、それらはグローバル変数にはなりません。これにより、グローバル名前空間の汚染が回避されます。またmain()、モジュールを別のモジュールからインポートした場合(スクリプトとして直接実行するのではなく)、関数が実行されないようにします。これは、インポート時に初期化(メッセージの印刷など)を実行したくないが、スタンドアロンスクリプトとして実行しているときに実行したい場合に便利です。

Pythonはどの関数を呼び出すかをどのように決定しますか

Pythonは、この意味で「オーバーロード」をサポートしていません。指定された名前空間には、指定された名前を持つ関数が1つだけ存在できます。同じ名前の2番目の関数(または同じクラスの同じ名前の2番目のメソッド)を作成すると、最初の関数が完全に上書きされます。

__init__.py

この質問は、他の人とはあまり関係がありません。しかし、いいえ、それはそれらを別の方法で処理しません。それらは別の時間に処理されます(パッケージ内のモジュールではなく、パッケージをインポートするとき)が、それらのコードは他のPythonファイルのコードとまったく同じように実行されます。

于 2013-03-24T16:58:54.413 に答える
1

Pythonのmain()は単なる関数名です。一般的なイディオム

if __name__ == '__main__':
    #do something

このファイルのコードがモジュールとしてインポートされるのではなく、プログラムとして実行されていることを理解するためのショートカットです。

Pythonはタイプフリーを目的としているため、コミュニティは規則とベストプラクティスに重点を置いています。これはコンパイラと同じレベルの予測可能性を提供しませんが、混乱を寄せ付けないようにするのに役立ちます。読みやすさはPythonのコアバリューであり、このようなイディオムは価値のある構造を提供します。

Pythonは、他の言語がサポートしているという意味で、関数のオーバーロードをサポートしていません。強く型付けされた言語では、同じ名前で入力引数が異なる同じ関数の複数のバージョンを作成できます。

void DoSomething (int a) {};
void DoSomething (float f) {};
void DoSomething (string s){};

Pythonには、同等のイディオムはありません。ほとんどの場合、これは不要です。数値演算の場合、入力番号がfloat、intなどであるかどうかは気にせず、正しい演算子をサポートしているだけです。ここで、「ダックタイピング」のPythonマントラが登場します。アヒルのように歩き、アヒルのようにクワクワクする場合は、アヒルです。そのため、 Python関数は、型をチェックするのではなく、着信引数で関数または演算子を慣用的に探します

インスタンスと静的メソッドの場合:Pythonでは、すべてのインスタンスメソッドは、関数の最初の引数として所有するインスタンスを暗黙的に取得します。

class Test(object):
    def __init__(self, arg):
        self.variable = arg
    def example(self):
        print self.variable

fred = Test(999)  # note: no 'self' passed here
fred.example()
>>> 999
joe = Test(-1)
joe.example()
>>> -1

クラスメソッドは、暗黙の最初の引数として、インスタンスではなくクラスタイプを取得します。クラスメソッドは、インスタンススコープではなくクラススコープで定義されているクラスレベルの変数を参照できますが、特定のインスタンスについては何も知りません。

class TestCls (Test)
   CLASS_VARIABLE = "hello"
   # other behavior inherited from Test

   @classmethod
   def class_example(cls):
       print cls.CLASS_VARIABLE


barney = TestCls(123)
barney.example()
>>> 123
barney.class_example() # again, no explicit class passed in
>>> 'hello'

静的メソッドは暗黙の引数をまったく取得しません。

class TestStatic (TestCls):
    CLASS_VARIABLE = 'goodbye'
    # inherited stuff again
    @staticmethod
    def static_test():
        print "behold, I have no implicit argument"

静的メソッドとクラスメソッドも、呼び出されるインスタンスを必要としません。

wilma = TestStatic(123)
wilma.static_test()  # you can call from an instance
>>> behold, I have no implicit argument
# or not:
TestStatic.static_test()
>>> behold, I have no implicit argument 
TestStatic.class_example()
>>> goodbye # the method is inherited, but the class variable come from this class
于 2013-03-24T17:15:47.110 に答える