如何动态调用Python函数

98 投票
11 回答
117467 浏览
提问于 2025-04-16 07:27

我有这段代码:

fields = ['name','email']

def clean_name():
    pass

def clean_email():
    pass

我该如何动态调用 clean_name()clean_email() 呢?

比如说:

for field in fields:
    clean_{field}()

我用了大括号,因为这是我在PHP中常用的写法,但显然这样不行。

那在Python中该怎么做呢?

11 个回答

53

有一个这样的函数字典会比直接在 globals() 里查找要好。

通常的做法是写一个包含这些函数的类:

class Cleaner(object):
    def clean_name(self):
        pass

然后可以用 getattr 来访问这些函数:

cleaner = Cleaner()
for f in fields:
    getattr(cleaner, 'clean_%s' % f)()

你甚至可以更进一步,做一些这样的事情:

class Cleaner(object):
    def __init__(self, fields):
        self.fields = fields

    def clean(self):
        for f in self.fields:
            getattr(self, 'clean_%s' % f)()

接着继承这个类,并在子类中声明你的 clean_<name> 方法:

cleaner = Cleaner(['one', 'two'])
cleaner.clean()

其实,这个方法还可以进一步扩展,让代码更整洁。第一步可能是用 hasattr() 来检查你的类中是否存在这样的函数。

69

使用 global 这个方法真的非常不好。你应该这样做:

fields = {'name':clean_name,'email':clean_email}

for key in fields:
    fields[key]()

把你的函数和它们对应的值放到一个字典里。

另外,使用 vars()[] 也是不对的。

83

如果你不想使用 globalsvars,也不想单独创建一个模块或者类来封装你想动态调用的函数,你可以直接把它们当作当前模块的属性来调用:

import sys
...
getattr(sys.modules[__name__], "clean_%s" % fieldname)()

撰写回答