开发者

What's the way to call a function dynamically in Python?

I would like to do something like:

dct = ['do_this', 'do_that']
dct[0]() //开发者_JAVA百科 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?

Explicitly I want to refer the function by name.


Functions are first-class objects in 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():

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

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


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():

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


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

dct = ['do_this', 'do_that']

getattr(my_module, dct[0])()

globals()[dct[0]]()


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

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


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.


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')()


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


Use getattrs()

dct = ['do_this', 'do_that']


getattr(class_object, dct[0])()

You can also dynamically call functions within classes via

inspect.getmembers(my_class, predicate=inspect.ismethod)

Then do a for loop and call getattr(class, methodname)

I think using getattr is more better suited for most cases, than using globals(). Globals() uses the global namespace scope of the entire program which may cause scope problems down the road.


To call the function dynamically which is defined in the same module, you can do this way:

import sys

## get the reference to the current module - key trick to get the ref to same module
this = sys.modules[__name__]

def foo():
  msg="I'm called dynamically!"
  return msg

## `fname` can be taken as an input from the user
fname='foo'

## get the reference to the function from the module
fn = getattr(this, fname)

## make the function call
fn()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜