この種のことを行うにはいくつかの方法があります。
「言語の外に出る」ことなく関数を記述できる場合は、Blenderの答えのように、ローカル関数を定義して返すことができます。これは通常、新しい関数を定義する必要があると思うときに必要なものです(Blenderの例を借りています)。
def make_func(a, b):
def f(n):
return n**a + b
return f
場合によっては、さらにうまく実行して、関数をデータとして表すことができます。たとえば、どのようにして任意の多項式関数を作成しますか?まあ、あなたはする必要はありません。係数と値のリストを取り、それを評価する一般的な多項式関数を持つことができます。その後、あなたがする必要があるのは係数リストを作成することです。
実際、これはあなたがここで欲しいものだと思います。あなたが言うように:
2 * f(n-1)-4 * f(n-2)-5 * f(n-3)+ 15 * f(n-4)1分を返すか、f(n-1)を返します。 + 3 * f(n-2)別、またはf(n-1)+ f(n-2)+ f(n-3)+ f(n-4)+ 5 * f(n-5)私が必要としているもの。
これは間違いなく係数のリストとして表すことができます。
def make_recursive_func(coefficients, baseval):
def f(n):
if n < len(coefficients): return baseval[n]
return sum(coefficient * f(n-i-1) for i, coefficient in enumerate(coefficients))
return f
eval_recursive_func(coefficients, baseval)
ただし、返された関数で行うのが、すぐに呼び出してから忘れるだけの場合は、単一の関数を作成する方がおそらくさらに簡単です。
まれにですが、決してではありませんが、実際にコードをその場で実行する必要がある場合があります。ひまんしゅが言うようにeval
、exec
そして友達はこれを行う方法です。例えば:
newcode = '''
def f(n):
if n<=3: return [0, 0, 6, 12][n]
return 2*f(n-1) - 4*f(n-2) - 5*f(n-3) + 15*f(n-4)
'''
exec(newcode)
これで、f
関数が定義されました。これを実行した場合とまったく同じです。
def f(n):
if n<=3: return [0, 0, 6, 12][n]
return 2*f(n-1) - 4*f(n-2) - 5*f(n-3) + 15*f(n-4)
Py3とPy2は少し異なり、実行するコンテキストや、実行するか、評価するか、コンパイルするか、インポートのように扱うかなどによって異なります。ただし、これが基本的な考え方です。
2番目ではなく1番目を書きたい理由がわからない場合は、これは必要ありません。
そして、その場で正しい文字列を生成する方法がわからない場合は、これを行うべきではありません。
また、Ignacio Vazquez-Abramsが指摘しているように、これらの関数をユーザー入力から構築できる場合は、通常は繰り返しコンパイルしてASTを実行することにより、安全であることを検証するために何かを行う必要があります。
最後に、さらにまれに、new
モジュール(および/またはinspect
)を使用して、他の関数オブジェクトのビットから(または手作りのバイトコードから)その場で新しい関数オブジェクトを作成する必要があります。しかし、それを行う方法を知る必要がある場合は、おそらくすでにその方法を知っています。