1. ホーム
  2. python

[解決済み] Pythonヘルパー関数のスコープ

2022-02-01 03:09:53

質問

つまり、入力が少し変わるだけで、基本的に同じことをするものがたくさんあるのです。これは、関数化され、異なるパラメータで毎回呼び出される完璧な候補ですよね?

どうやら、pythonは私が間違っていると考えているようです。

そこで、私の問題を煮詰めてみると、次のようになります。

def main():
    x = 10

    def helper(n):
      if (x > n):
          x -= n

ヘルパー関数には他にも何十行もあり、メインでも何十回も呼び出されていますが、問題を引き起こしているのはこの行です。ヘルパー関数がmainのスコープを使わずにローカルスコープを使っているのは分かっているのですが、なぜなのか、どうすれば修正できるのか、というのが質問です。

xをグローバルにしたいわけではなく、ヘルパーが自分で作るのではなく、すでにあるxを使いたいだけなのです。このヘルパー関数がなければ、コードの総行数は少なくとも4倍になり、コードは複雑で読みにくい混乱したものになるでしょう。

EDIT: あと、Mainはxを大量に使うから、ローカルで定義するわけにはいかないんだ、念のため。

解決方法は?

Python 3 では、このようなことは nonlocal x をインナー関数に追加します。 Python 2ではそれができません。

しかし、その代わりにできることは、ヘルパー関数から値を返し、ヘルパー関数を呼び出す場所にそれを代入することです。 この例からではちょっとわかりにくいですが、次のような使い方をしているのでしょう。

def main():
    x = 10

    def helper(n):
        if (x > n):
            x -= n

    # do something that changes x
    helper(2)
    # now x has changed

その代わり、こうしてください。

def helper(x, n):
    if (x > n):
        return x - n
    else:
        return x

def main():
    x = 10

    # do something that changes x
    x = helper(x, 2)
    # now x has changed

このアイデアは、ヘルパー関数に必要な値を渡し、その結果を返してもらうことで、ヘルパーが呼び出された場所で代入(または好きなように)することができます。 ヘルパー関数が呼び出し元の変数を直接変更するのとは対照的に、 この方法はコードの追跡を容易にします。 また、ここでは helper 外側 main となり、両者がよりきれいに分離され、さらに helper を他の機能で使用できるようにしました。