簡體   English   中英

Python:將函數名稱作為函數中的參數傳遞

[英]Python: Passing a function name as an argument in a function

我試圖將一個函數的名稱作為參數傳遞給另一個函數,但出現錯誤:“類型錯誤:‘str’對象不可調用”。 這是問題的一個簡化示例:

def doIt(a, func, y, z):
    result = z
    result = func(a, y, result)
    return result

def dork1(arg1, arg2, arg3):
    thing = (arg1 + arg2) / arg3
    return thing

def dork2(arg1, arg2, arg3):
    thing = arg1 + (arg2 / arg3)
    return thing

當我像這樣調用 doIt 時:

var = 'dork1'
ned = doIt(3, var, 4, 9)
print (ned)

我得到:

Traceback (most recent call last):
   File "<pyshell#9>", line 1, in <module>
     ned = doIt(3, var, 4, 9)
   File "<pyshell#2>", line 3, in doIt
     result = func(a, y, result)
TypeError: 'str' object is not callable

如果你想傳遞函數的name ,正如你所說的和你正在做的,當然你不能調用它——為什么要“調用一個名字”? 毫無意義。

如果要調用它,傳遞函數本身,即最強調

var = 'dork1'

反而

var = dork1

沒有引號!

編輯:OP 在評論(!)中想知道如何在給定函數名稱(作為字符串)的情況下獲取函數對象。 碰巧我剛剛在我在 OSCON 教過的教程中展示了如何做到這一點(我剛回來)——從這里獲取幻燈片並查看第 47 頁,“延遲加載回調”:

class LazyCallable(object):
  def __init__(self, name):
    self.n, self.f = name, None
  def __call__(self, *a, **k):
    if self.f is None:
      modn, funcn = self.n.rsplit('.', 1)
      if modn not in sys.modules:
        __import__(modn)
      self.f = getattr(sys.modules[modn],
                       funcn)
    self.f(*a, **k)

所以你可以通過LazyCallable('somemodule.dork1')LazyCallable('somemodule.dork1')過上幸福的生活。 如果您當然不需要處理模塊(這一定意味着多么奇怪的架構!-),調整此代碼很容易。

我很高興找到這個,我不知道這是否得到了回答。 我對此的解決方案如下:

def doIt(func, *args):
   func_dict = {'dork1':dork1,'dork2':dork2}
   result = func_dict.get(func)(*args)
   return result

def dork1(var1, var2, var3):
   thing = (float(var1 + var2) / var3)
   return thing

def dork2(var1, var2, var3):
   thing = float(var1) + (float(var2) / var3)
   return thing

這可以按如下方式運行:

func = 'dork2'
ned = doIt(func,3, 4, 9)
print ned

不要傳遞函數的名稱。

傳遞函數。

fun = dork1
ned = doIt(3, fun, 4, 9)
print (ned)
var = 'dork1'
ned = doIt(3, var, 4, 9)
print (ned)

在這個例子中, var是一個字符串。 doIt函數“調用”它的第二個參數(為此傳遞var )。 改為傳遞一個函數。

您可能不應該這樣做,但您可以使用 eval() 獲取該函數

例如,要使用 len,

eval("len")(["list that len is called on"])
def run_function(function_name):
    function_name()

在這個例子中,調用run_function(any_function)將調用any_function()

函數是python中的一等對象。 做這個:

var = dork1

如果必須傳遞字符串,例如用戶輸入,則:

globals()[var]

將查找函數對象。

class renderAttributes():
    def __init__(self, name):
        self.name = name
    def decorator_function(self, func_name):
        func_dict = {'my_function': self.my_function}
        def wrapper_function():
            result = func_dict.get(func_name)()
            return result
        return wrapper_function
    def my_function(self):
        //Do whatever you want to do
        return self.name

然后我可以創建一個 renderAttributes 類的對象,並通過簡單地傳遞函數名稱來調用類中定義的任何方法,如下所示

render_attr_obj = renderAttributes('Bob')
return_function = render_attr_obj.decorator_function('my_function')
return_functon() 
return_function = renderAttributes('Rob')
return_function = render_attr_obj.decorator_function('my_function')
return_functon() 

如果這些函數是類的一部分,則getattr可能會起作用。

class SomeClass():
    def doIt(self, a, func, y, z):
        result = z
        result = getattr(self, func)(a, y, result)
        return result

    def dork1(self, arg1, arg2, arg3):
        thing = (arg1 + arg2) / arg3
        return thing

    def dork2(self, arg1, arg2, arg3):
        thing = arg1 + (arg2 / arg3)
        return thing

嘗試從sys.argv傳遞函數名稱時,它對我有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM