2010-02-17 117 views
54

我有存儲在一個變量這樣的功能名稱:Python函數指針

myvar = 'mypackage.mymodule.myfunction' 

我現在想調用的MyFunction這樣

myvar(parameter1, parameter2) 

什麼是實現這一目標的最簡單的方法是什麼?

+4

爲什麼不存儲函數本身? 'myvar = mypackage.mymodule.myfunction'要乾淨得多。 – ironfroggy 2010-02-17 18:54:43

+1

從下面的評論:«它必須是一個字符串,因爲在它定義的地方,應用程序不知道所需的功能,因爲它是一個通用的應用程序。» - schneck – badp 2010-02-17 19:35:16

回答

81
​​
+1

+1很好的答案。 – 2010-02-17 18:30:26

+0

最後,您的解決方案最符合我的需求,謝謝。 – schneck 2010-02-17 20:37:23

+0

我想知道如果這個函數被稱爲很多次(在一個循環,遞歸等等)中,那麼性能會如何? – zanlok 2011-02-02 13:34:41

7

最簡單的

eval(myvar)(parameter1, parameter2) 

你沒有一個功能 「指針」。你有一個「名字」功能。

雖然這很有效,但您會有大量人告訴您這是「不安全」或「安全風險」。

+1

「insecure」:如果myvar來自用戶輸入,是的:) – 2010-02-17 18:12:12

+20

他們會是「正確的」。 – 2010-02-17 18:12:34

+6

...而那些大量的人是正確的。 – Triptych 2010-02-17 18:12:44

13
def f(a,b): 
    return a+b 

xx = 'f' 
print eval('%s(%s,%s)'%(xx,2,3)) 

輸出

5 
+0

我會給予upvote來抵消downvote。這可能不是最好的解決方案,我認爲這是一個有用的答案,因爲它顯示了一個完整的工作示例。 – 2010-02-17 18:23:39

+0

@ Bryan Oakley歡呼! – 2010-02-17 18:31:46

+4

eval是魔鬼,imo – zanlok 2011-02-02 13:35:59

4
modname, funcname = myvar.rsplit('.', 1) 
getattr(sys.modules[modname], funcname)(parameter1, parameter2) 
5

爲什麼不能存儲函數本身? myvar = mypackage.mymodule.myfunction更清潔。

33

能夠存儲函數本身更好,因爲它們是python中的第一類對象。

import mypackage 

myfunc = mypackage.mymodule.myfunction 
myfunc(parameter1, parameter2) 

但是,如果你要動態導入的包,那麼你就可以做到這一點通過:

mypackage = __import__('mypackage') 
mymodule = getattr(mypackage, 'mymodule') 
myfunction = getattr(mymodule, 'myfunction') 

myfunction(parameter1, parameter2) 

熊但是記住,所有的工作都適用於你的任何範圍目前如果你不以某種方式堅持它們,那麼如果你離開本地範圍,你不能指望它們留在附近。

1

eval(compile(myvar,'<str>','eval'))(myargs)

編譯(...,「EVAL」)僅允許一個語句,因此有不能任意命令的電話後,還是會有一個SyntaxError。然後,一小部分的驗證至少可以將表達限制在某種能力上,比如測試'mypackage'開始。

1

我在創建一個庫來處理認證時遇到了類似的問題。我希望使用我的庫的應用程序所有者能夠在庫中註冊一個回調,以檢查授權人員所在的LDAP組的授權。配置將作爲一個config.py文件傳入並且包含一個dict與所有的配置參數。

我得到這個工作:

>>> class MyClass(object): 
...  def target_func(self): 
...   print "made it!" 
...  
...  def __init__(self,config): 
...   self.config = config 
...   self.config['funcname'] = getattr(self,self.config['funcname']) 
...   self.config['funcname']() 
... 
>>> instance = MyClass({'funcname':'target_func'}) 
made it! 

是否有一個Python的-ER的方式來做到這一點?