90

このようなPythonコードでどのようなメリットや影響が得られるでしょうか。

class some_class(parent_class):
    def doOp(self, x, y):
        def add(x, y):
            return x + y
        return add(x, y)

私はこれをオープンソースプロジェクトで見つけました。ネストされた関数の内部で何か便利なことをしていますが、それを呼び出す以外はまったく何もしていません。(実際のコードはここにあります。)なぜ誰かがこのようにコーディングするのでしょうか?外側の通常の関数ではなく、ネストされた関数内にコードを記述することには、いくつかの利点または副作用がありますか?

4

6 に答える 6

118

通常、あなたはクロージャを作るためにそれをします:

def make_adder(x):
    def add(y):
        return x + y
    return add

plus5 = make_adder(5)
print(plus5(12))  # prints 17

内部関数は、囲んでいるスコープから変数(この場合はローカル変数x)にアクセスできます。囲んでいるスコープから変数にアクセスしていない場合、それらは実際には異なるスコープを持つ通常の関数にすぎません。

于 2009-10-19T16:05:56.380 に答える
61

内部関数の作成がほとんど関数発生器の定義である関数発生器を除いて、ネストされた関数を作成する理由は、読みやすさを向上させるためです。外部関数によってのみ呼び出される小さな関数がある場合は、定義をインライン化するので、その関数が何をしているのかを判断するためにスキップする必要はありません。後日関数を再利用する必要がある場合は、いつでも内部メソッドをカプセル化メソッドの外に移動できます。

おもちゃの例:

import sys

def Foo():
    def e(s):
        sys.stderr.write('ERROR: ')
        sys.stderr.write(s)
        sys.stderr.write('\n')
    e('I regret to inform you')
    e('that a shameful thing has happened.')
    e('Thus, I must issue this desultory message')
    e('across numerous lines.')
Foo()
于 2009-10-19T15:03:11.013 に答える
27

内部メソッドを使用することの潜在的な利点の1つは、外部メソッドのローカル変数を引数として渡さずに使用できることです。

def helper(feature, resultBuffer):
  resultBuffer.print(feature)
  resultBuffer.printLine()
  resultBuffer.flush()

def save(item, resultBuffer):

  helper(item.description, resultBuffer)
  helper(item.size, resultBuffer)
  helper(item.type, resultBuffer)

次のように書くことができます。

def save(item, resultBuffer):

  def helper(feature):
    resultBuffer.print(feature)
    resultBuffer.printLine()
    resultBuffer.flush()

  helper(item.description)
  helper(item.size)
  helper(item.type)
于 2012-11-15T12:32:05.640 に答える
8

私はそのようなコードの正当な理由を想像することはできません。

たぶん、他のOpsのように、古いリビジョンの内部機能には理由がありました。

たとえば、これは少し意味があります。

class some_class(parent_class):
    def doOp(self, op, x, y):
        def add(x, y):
            return x + y
        def sub(x,y):
            return x - y
        return locals()[op](x,y)

some_class().doOp('add', 1,2)

ただし、内部関数は代わりに( "private")クラスメソッドである必要があります。

class some_class(object):
    def _add(self, x, y):
        return x + y
    def doOp(self, x, y):
        return self._add(x,y)
于 2009-10-19T14:55:37.313 に答える
6

ローカルメソッドの背後にある考え方は、ローカル変数に似ています。より大きな名前空間を汚染しないでください。ほとんどの言語はそのような機能を直接提供しないため、明らかに利点は限られています。

于 2009-10-19T14:57:24.720 に答える
1

コードはまさにこのようなものでしたか?このようなことを行う通常の理由は、パーシャル(ベイクインされたパラメーターを持つ関数)を作成するためです。外部関数を呼び出すと、パラメーターを必要としない呼び出し可能オブジェクトが返されるため、パラメーターを渡すことができない場所に保管して使用することができます。ただし、投稿したコードはそれを行いません。呼び出し可能ではなく、関数をすぐに呼び出して結果を返します。見た実際のコードを投稿すると便利な場合があります。

于 2009-10-19T14:59:37.013 に答える