9

C/Java の背景を持つ python に移行して、最近相互再帰を実装する必要がありましたが、python の何かが気になりました:

Python プログラムは行ごとに解釈されるため、同じ Python ファイルに 2 つの関数が次々にある場合:

def A(n):
    B(n-1)
# if I add A(1) here, it gives me an error
def B(n):
    if n <= 0:
        return
    else:
        A(n-1)

インタプリタが を読んでいるとき、ABまだ定義されていませんが、このコードはエラーになりません

私の理解では、defが解釈されると、python は を使用してローカル名前空間にエントリを追加しますlocals(){"function name": function address}、関数本体に関しては、構文チェックのみを行います。

def A():
    blabla # this will give an error

def B():
    print x # even though x is not defined, this does not give an error
    A()     # same as above, NameError is only detected during runtime
4

3 に答える 3

5

行には、「このステートメントが実行されると、モジュールスコープ内のB(n-1)関数を検索し、パラメーターを指定して呼び出す」と書かれています。関数の実行時にルックアップが行われるため、後で定義できます。Bn-1B

B(さらに、別の関数で完全に上書きして、後でA新しい関数を呼び出すBこともできます。しかし、それはコードを混乱させる可能性があります。)

存在しない関数の呼び出しをキャッチできないことが心配な場合は、静的分析ツールを使用してみてください。それ以外は、コードをテストしていることを確認してください。

于 2015-10-08T21:56:33.103 に答える
4

ASyntaxErrorはコンパイル時に捕捉されますが、他のほとんどのエラー ( NameErrorValueErrorなど) は実行時にのみ捕捉され、その後、その関数が呼び出された場合にのみ捕捉されます。

「もし私が関数を書いたら、それが私のテストで呼び出されなければ..」 - そしてそれがあなたがすべてをテストするべき理由です。

一部の IDE ではさまざまな状況で警告が表示されますが、最適なオプションは、自分で徹底的にテストすることです。このようにして、IDE の自動チェックではカバーできない、ユーザー入力などの要因によって発生するエラーをチェックすることもできます。

于 2015-10-08T21:57:19.513 に答える
0

インタープリターが A を読み取っている場合、B はまだ定義されていませんが、このコードではエラーは発生しません

Python インタープリターがエラーを出さない理由は、技術的に前方参照と呼ばれるdocsから見つけることができます。

自由変数の名前解決は、コンパイル時ではなく実行時に行われます。

于 2016-05-29T13:42:06.447 に答える