2009-04-13 73 views
6

這是我可以爲該主題提出的最好名稱,我的搜索都沒有提供與該問題相關的信息。調用未知的Python函數

如何調用一個函數從字符串,即

functions_to_call = ["func_1", "func_2", "func_3"] 

for f in functions_to_call: 
    call f 
+0

當你似乎知道你想從列表中調用它們的函數時,它是如何未知的函數 – 2009-04-13 17:45:21

+0

函數名可能來自外部源,如文本文件。 – gregturn 2009-04-13 18:37:23

+0

這意味着它是一個運行遊戲的半抽象系統(所以我可以重複使用它),因此它們將會接近文本文件。 – Teifion 2009-04-13 22:46:15

回答

2
functions_to_call = ["func_1", "func_2", "func_3"] 

for f in functions_to_call: 
    eval(f+'()') 

編輯補充:

是,eval()函數通常是一個壞主意,但是這是什麼OP正在尋找。

+0

這工作完美,我不知道爲什麼它有這麼幾個upvotes。 – Teifion 2009-04-13 17:36:51

+0

-1沒有提到eval的使用是一個糟糕的主意。確實是 – nosklo 2009-04-13 17:38:46

+2

。在這裏沒有理由使用eval()。 '本地人()[f]()'會很好。這仍然是一個非常可疑的方式,但比eval()更好。 – bobince 2009-04-13 18:13:04

15

你怎麼知道要調用的函數的名字?存儲功能而不是名稱:

functions_to_call = [int, str, float] 

value = 33.5 

for function in functions_to_call: 
    print "calling", function 
    print "result:", function(value) 
+0

我可以解釋有關確切程序的所有內容,但我認爲這會浪費空間並分散手頭的具體問題。 – Teifion 2009-04-13 17:19:15

+0

函數在問題中存儲爲字符串,而不是在答案中存儲,所以答案並不完全正確...... – sykora 2009-04-13 17:21:13

+1

@sykora ...但是如果您可以扭轉問題的要求,它確實顯示出更好的方式一點點。 – 2009-04-13 17:24:02

1

查看eval and compile的功能。

該函數也可以用來執行任意代碼對象(比如由compile()創建的那些對象)。在這種情況下,傳遞一個代碼對象而不是一個字符串。如果代碼對象已經用'exec'作爲kind參數編譯,則eval()的返回值將是None。

+0

-1沒有提及exec/eval的使用是一個糟糕的主意。 – nosklo 2009-04-13 17:37:35

8

類似的東西...當我看着在Python函數指針..

def myfunc(x): 
    print x 

dict = { 
    "myfunc": myfunc 
} 

dict["myfunc"]("hello") 

func = dict.get("myfunc") 
if callable(func): 
    func(10) 
+0

如果你確實需要一個字符串 – nosklo 2009-04-13 17:35:19

+0

「函數指針」,那麼+1調度字典是一個很好的方法嗎?沒有這樣的事。 – 2009-04-13 21:26:46

+0

是的...我知道...我正在尋找相當於... – LB40 2009-04-14 12:45:09

19

您可以使用Python內置的當地人()來獲取局部聲明,如:

def f(): 
    print "Hello, world" 

def g(): 
    print "Goodbye, world" 

for fname in ["f", "g"]: 
    fn = locals()[fname] 
    print "Calling %s" % (fname) 
    fn() 

您可以使用「imp」模塊從用戶指定的python文件加載函數,這給您更多的靈活性。

使用locals()確保你不能叫通用蟒蛇,而使用的eval,你可以與用戶最終的字符串設定爲像某種不利:

f = 'open("/etc/passwd").readlines' 
print eval(f+"()") 

或相似,並且結了你的編程做你認爲不可能的事情。通常使用類似的技巧與本地人()和字典,只會給攻擊者KeyErrors。

+0

你是一個惡性混蛋nosklo。他*做了很好的解釋 – mpen 2009-04-13 18:13:30

+0

@Mark:的確如此。我評論了錯誤的答案,對不起。刪除。 – nosklo 2009-04-13 18:26:08

1

不要使用eval!它幾乎從來沒有要求的,在Python函數只是屬性和其他事物一樣,而且無論是在一類使用getattr,或通過locals()訪問:

>>> print locals() 
{'__builtins__': <module '__builtin__' (built-in)>, 
'__doc__': None, 
'__name__': '__main__', 
'func_1': <function func_1 at 0x74bf0>, 
'func_2': <function func_2 at 0x74c30>, 
'func_3': <function func_3 at 0x74b70>, 
} 

由於這是一本字典,你可以通過dict-獲得的功能鍵func_1func_2func_3

>>> f1 = locals()['func_1'] 
>>> f1 
<function func_1 at 0x74bf0> 
>>> f1() 
one 

所以,而不訴諸解決EVAL:

>>> def func_1(): 
...  print "one" 
... 
>>> def func_2(): 
...  print "two" 
... 
>>> def func_3(): 
...  print "three" 
... 
>>> functions_to_call = ["func_1", "func_2", "func_3"] 
>>> for fname in functions_to_call: 
...  cur_func = locals()[fname] 
...  cur_func() 
... 
one 
two 
three