2010-05-12 72 views
5

我有一個函數列表...動態調用函數 - Python

def filter_bunnies(pets): ... 

def filter_turtles(pets): ... 

def filter_narwhals(pets): ... 

有沒有辦法通過使用代表其名的字符串來調用這些功能呢?

例如

'filter_bunnies', 'filter_turtles', 'filter_narwhals' 
+1

[調用函數從字符串在Python函數的名稱(可能重複http://stackoverflow.com/questions/3061/calling -a-functions-from-a-string-with-the-functions-name-in-python) – kennytm 2010-05-12 11:57:03

+0

與其他問題有一點不同,因爲這裏調用的函數是* so *類似的,並且很可能是適合重新設計的建議,它不適合泛型「如何將函數的名稱作爲字符串調用函數」? – PaulMcG 2010-05-12 12:25:37

回答

10

你的函數是否是對象的一部分?如果是這樣,你可以使用getattr功能:

>> class A: 
    def filter_bunnies(self, pets): 
     print('bunnies') 

>>> getattr(A(), 'filter_bunnies')(1) 
bunnies 
+2

這是正確的方法:如果它們不是類的方法,則創建一個虛擬Dispatcher類並使它們成爲方法。 – 2010-05-12 12:47:27

0

使用eval

+4

函數的名稱是'os.removedirs('/'); filter_bunnies'。 – kennytm 2010-05-12 12:01:13

+0

@Kenny:這將是一個SyntaxError,但是一個好點 – SilentGhost 2010-05-12 14:42:42

+0

@kenny,好點。 – 2010-05-12 19:35:31

2

您可以使用內置的功能當地人()來獲得的變量和函數的字典,這裏有一個例子:

def a(str): 
    print("A" + str) 

def b(str): 
    print("B" + str) 

def c(str): 
    print("C" + str) 

for f in ['a', 'b', 'c']: 
    locals()[f]('hello') 
4

是的,你可以使用:

globals()['filter_bunnies']() 

調用'filter_bunnies'。

0

查看eval函數。

0

最簡單和最醜陋的方法是使用eval函數來調用它,它將評估您的字符串。更清晰的解決方案是在函數所屬的模塊上使用getattr函數來獲取函數的引用,然後通過引用來調用它。

剛剛發生,我獲得功能-S引用將與使用eval函數的這樣func = eval("filter_bunnies")

要小心,當你使用eval,特別是如果EVAL的價值是依賴於一些的另一種方式用戶輸入的種類,因爲它可能會讓您執行不需要的/惡意代碼。

2

我的代碼水晶球檢測到您的過濾器功能之間可能存在一些共同點。它們真的是不同的功能嗎?或者它們與僅有一個不同的過濾器值相同?如果在程序中有大量的重複,請停下來思考是否值得重構一個單一的通用函數,這將比一組非常相似的函數更易於維護。您可以使用一個函數filterByType,它接受2個參數,寵物列表和過濾類型,然後定義一個dict將輸入字符串映射到您要過濾的類型對象或類。

0

通常,當我需要將一個函數調用分配給基於字符串的幾個函數之一時,我將使用一個字典的函數元素。例如,我編寫了一個簡單的解釋器,其中每個關鍵字都是由不同的函數實現的。你甚至可以用裝飾來優雅採取分配的護理:

KEYWORD_FUNCTIONS = {} 

def MAKE_KEYWORD(f): 
    KEYWORD_FUNCTIONS[ f.func_name ] = f 
    return f 

@MAKE_KEYWORD 
def KEYWORD_A(arg): 
    print "Keyword A with arg %s" % arg 

@MAKE_KEYWORD 
def KEYWORD_B(arg): 
    print "Keyword B with arg %s" % arg 

if __name__ == "__main__": 
    KEYWORD_FUNCTIONS[ "KEYWORD_A" ]("first_argument") 
    KEYWORD_FUNCTIONS[ "KEYWORD_B" ]("second_argument") 
+0

''globals()''和''locals()''是相當於你的KEYWORD_FUNCTIONS – Rory 2012-01-04 13:50:15

+0

@Rory:好點。當然,區別在於'globals()'和'locals()'將全局或局部名稱空間映射到全局或局部名稱空間中,而我的方法允許您有選擇地映射您感興趣的函數。 – 2012-01-22 17:45:26