Python有没有像PHP的call_user_func()功能?

1 投票
5 回答
2837 浏览
提问于 2025-04-15 11:33

Python有没有像PHP里的call_user_func()这样的函数呢?

PHP版本:

call_user_func(array($object,$methodName),$parameters)    

我该如何在Python中实现上面的功能呢?

5 个回答

4

如果你需要使用一些远处的类(实际上,如果你需要任何类的话),那么最好的办法就是创建一个字典来管理它们:

funcs = {'Eggs': foo.Eggs, 'Spam': bar.Spam}

def call_func(func_name, *args, **kwargs):
    if not func_name in funcs:
        raise ValueError('Function %r not available' % (func_name,))
    return funcs[func_name](*args, **kwargs)
9

我看不出有什么问题,除非 methodName 是一个字符串。如果是这样的话,getattr 可以解决这个问题:

>>> class A:
...     def func(self, a, b):
...         return a + b
... 
>>> a = A()
>>> getattr(a, 'func')(2, 3)
5

如果 object 也是一个字符串,那么可以使用 globalslocals 来实现(不过那样可能会有其他更大的问题):

>>> getattr(locals()['a'], 'func')(2, 3)
5
>>> getattr(globals()['a'], 'func')(2, 3)
5

编辑:关于你的澄清。如果要根据字符串初始化一个对象:

>>> class A:
...     def __init__(self): print('a')
... 
>>> class B:
...     def __init__(self): print('b')
... 
>>> clsStr = 'A'
>>> myObj = locals()[clsStr]()
a

不过我不太确定这是否真的是你想要的……除非你有很多不同的类,否则为什么不直接进行字符串匹配呢?


另一个编辑:虽然上面的做法可以,但你应该认真考虑使用 Ignacio Vazquez-Abrams 提供的解决方案。首先,通过将所有可能的类存储在一个 dict 中,你可以避免因为传入了一个错误的字符串参数而导致的奇怪行为,这个字符串恰好与当前作用域中某个不相关类的名字相匹配。

2

选择要创建哪个对象其实并不难。类本身就是一种重要的对象,可以赋值给一个变量,或者作为参数传递给一个函数。

class A(object):
    def __init__( self, arg1, arg2 ):
         etc.

class B(object):
    def __init__( self, arg1, arg2 ):
         etc.

thing_to_make = A
argList= ( some, pair )
thing_to_make( *argList )

thing_to_make = B
argList- ( another, pair )
thing_to_make( *argList )

def doSomething( class_, arg1, arg2 ):
    thing= class_( arg1, arg2 )
    thing.method()
    print thing

这一切都很顺利,没有太多麻烦。在Python中,你不需要像“call_user_function”这样的东西。

撰写回答