在Python中动态调用函数的方法是什么?

时间:2022-12-05 14:30:01

I would like to do something like:

我想做的事情如下:

dct = ['do_this', 'do_that']
dct[0]() // call do_this

But you can't call the string as a function (will get an error).

但是你不能将字符串作为函数调用(会出错)。

How can I achieve this without switching and without using a list of lambdas or functions?

如何在不切换和不使用lambdas或函数列表的情况下实现此目的?

Explicitly I want to refer the function by name.

显然我想按名称引用函数。

7 个解决方案

#1


8  

Functions are first class objects. So like this:

函数是第一类对象。像这样:

def do_this():
    print "In do_this"

def do_that():
    print "In do_that"

dct = [do_this, do_that]
dct[0]()

If you really want to call them from a string list you can use globals():

如果你真的想从字符串列表中调用它们,你可以使用globals():

dct = ['do_this', 'do_that']
globals()[dct[0]]()

But I would suggest that using globals() (or locals()) probably isn't the right way to solve your problem. Grok the python way: >>> import this

但我建议使用globals()(或locals())可能不是解决问题的正确方法。 Grok的python方式:>>>导入这个

#2


11  

Functions are first-class objects in Python:

函数是Python中的第一类对象:

def do_this():
    pass

def do_that():
    pass

dct = [do_this, do_that]
dct[0]()  # calls do_this()

If dct absolutely has to be a list of strings, I'd go with eval():

如果dct必须是一个字符串列表,我会选择eval():

eval(dct[0] + "()")

It's not pretty, but switching between globals() and getattr() on the proper module can be a pain.

它并不漂亮,但在正确的模块上切换globals()和getattr()可能会很痛苦。

#3


2  

You can use getattr if they are in a module or globals() if they are in the global namespace:

如果它们位于模块中,则可以使用getattr;如果它们位于全局命名空间中,则可以使用globals():

dct = ['do_this', 'do_that']

getattr(my_module, dct[0])()

globals()[dct[0]]()

#4


1  

If the functions you want to call are part of a module:

如果要调用的函数是模块的一部分:

import module
getattr(module, funcname_string)(*args, **kwargs)

#5


1  

As others have said, functions in Python are first-class objects. If you really want to get their names from a list, you can either use eval() (not popular) or use the globals() dictionary. Keep in mind that if these strings come from users, they're pretty dangerous. And if they don't come from users, then don't use strings.

正如其他人所说,Python中的函数是一流的对象。如果你真的想从列表中获取它们的名字,你可以使用eval()(不受欢迎)或使用globals()字典。请记住,如果这些字符串来自用户,则它们非常危险。如果他们不是来自用户,那么不要使用字符串。

#6


1  

having the functions in some dict or in a class or instance

在某些词典或类或实例中具有该功能


def fn_a():
    pass

some_dict = {
    'fn_a': fn_a,
}

class Someclass(object):

  @classmethod
  def fn_a(cls):
    pass

  # normal instance method
  def fn_b(self):
    pass

some_instance = Someclass()

you could do: some_dict['name']() or getattr(some_instance, 'fn_b')() or getattr(Someclass, 'fn_a')()

你可以这样做:some_dict ['name']()或getattr(some_instance,'fn_b')()或getattr(Someclass,'fn_a')()

#7


1  

def do_this(): pass
def do_that(): pass

dct = dict((x.__name__, x) for x in [do_this, do_that])
# dct maps function names to the function objects
# the names *don't* have to match the function name in your source:
#   dct = {"foo": do_this}
# which means user-facing names can be anything you want

dct["do_this"]()  # call do_this

#1


8  

Functions are first class objects. So like this:

函数是第一类对象。像这样:

def do_this():
    print "In do_this"

def do_that():
    print "In do_that"

dct = [do_this, do_that]
dct[0]()

If you really want to call them from a string list you can use globals():

如果你真的想从字符串列表中调用它们,你可以使用globals():

dct = ['do_this', 'do_that']
globals()[dct[0]]()

But I would suggest that using globals() (or locals()) probably isn't the right way to solve your problem. Grok the python way: >>> import this

但我建议使用globals()(或locals())可能不是解决问题的正确方法。 Grok的python方式:>>>导入这个

#2


11  

Functions are first-class objects in Python:

函数是Python中的第一类对象:

def do_this():
    pass

def do_that():
    pass

dct = [do_this, do_that]
dct[0]()  # calls do_this()

If dct absolutely has to be a list of strings, I'd go with eval():

如果dct必须是一个字符串列表,我会选择eval():

eval(dct[0] + "()")

It's not pretty, but switching between globals() and getattr() on the proper module can be a pain.

它并不漂亮,但在正确的模块上切换globals()和getattr()可能会很痛苦。

#3


2  

You can use getattr if they are in a module or globals() if they are in the global namespace:

如果它们位于模块中,则可以使用getattr;如果它们位于全局命名空间中,则可以使用globals():

dct = ['do_this', 'do_that']

getattr(my_module, dct[0])()

globals()[dct[0]]()

#4


1  

If the functions you want to call are part of a module:

如果要调用的函数是模块的一部分:

import module
getattr(module, funcname_string)(*args, **kwargs)

#5


1  

As others have said, functions in Python are first-class objects. If you really want to get their names from a list, you can either use eval() (not popular) or use the globals() dictionary. Keep in mind that if these strings come from users, they're pretty dangerous. And if they don't come from users, then don't use strings.

正如其他人所说,Python中的函数是一流的对象。如果你真的想从列表中获取它们的名字,你可以使用eval()(不受欢迎)或使用globals()字典。请记住,如果这些字符串来自用户,则它们非常危险。如果他们不是来自用户,那么不要使用字符串。

#6


1  

having the functions in some dict or in a class or instance

在某些词典或类或实例中具有该功能


def fn_a():
    pass

some_dict = {
    'fn_a': fn_a,
}

class Someclass(object):

  @classmethod
  def fn_a(cls):
    pass

  # normal instance method
  def fn_b(self):
    pass

some_instance = Someclass()

you could do: some_dict['name']() or getattr(some_instance, 'fn_b')() or getattr(Someclass, 'fn_a')()

你可以这样做:some_dict ['name']()或getattr(some_instance,'fn_b')()或getattr(Someclass,'fn_a')()

#7


1  

def do_this(): pass
def do_that(): pass

dct = dict((x.__name__, x) for x in [do_this, do_that])
# dct maps function names to the function objects
# the names *don't* have to match the function name in your source:
#   dct = {"foo": do_this}
# which means user-facing names can be anything you want

dct["do_this"]()  # call do_this