有很多方法可以做這種事情。
如果該功能可以在沒有「跨越語言」的情況下進行描述,那麼您可以定義一個本地函數並返回它,就像在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) (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)
,如果你曾經要與返回的函數來完成所有的呼叫它立即,然後忘記它。
有時 - 很少,但不是永遠 - 您確實需要執行代碼。正如Himanshu所說,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)
它在PY 3比的Py2有點不同,有根據的變化你希望執行什麼樣的上下文,或者你是否希望它執行或評估或編譯或像導入一樣對待等。但這是基本思想。
如果你想不出爲什麼要寫第一個而不是第二個,那麼你不需要這個。
如果你無法弄清楚如何快速生成正確的字符串,你不應該這樣做。正如Ignacio Vazquez-Abrams所指出的,如果這些函數可以由用戶輸入構建出來,則需要通過迭代編譯和行走AST來做一些事情來驗證它們是否安全。
最後,更是很少,你需要使用new
模塊(和/或inspect
)創建一個新的函數對象上飛出來的其他功能對象(甚至從手工製作的字節碼)位。但是如果你需要知道如何做到這一點,你可能已經知道如何做。
你要完成的任務叫做_metaprogramming._ –
你想在哪一點創建這些功能?從運行期間的「用戶輸入」?或者像你在提供一個插件模塊一樣動態,在啓動時會加載一堆函數? – jdi
你需要更具體。你是如何創建這些功能的?是否必須以程序文本的形式,而不是以本地定義的函數(或lambda)或驅動不同函數的數據爲形式?如果您真的需要即時評估文本,有辦法做到這一點(甚至可以使用手動編譯的字節碼來創建函數......),但是如果可能的話,應該避免這樣做,因爲它通常是錯誤的答案在Python中。 – abarnert