Есть ли в Python call_user_func () как PHP? - PullRequest
0 голосов
/ 13 мая 2009

Есть ли в Python такая функция, как call_user_func() в PHP?

Версия PHP:

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

Как мне достичь вышеуказанного в Python?

Ответы [ 5 ]

8 голосов
/ 13 мая 2009

Я не вижу проблемы, если только methodName не является строкой. В этом случае getattr выполняет работу:

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

Если object также является строкой, то это будет работать, используя globals или locals (но тогда у вас могут быть другие, более серьезные проблемы):

>>> 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

Я не уверен, что это действительно то, что вам нужно, хотя ... если у вас не много разных классов, почему бы просто не выполнить сопоставление строк?


Другое редактирование : Несмотря на то, что вышеприведенное работает, вы должны серьезно подумать о том, чтобы воспользоваться решением, таким как Игнасио Васкес-Абрамс . Во-первых, сохраняя все возможные классы в dict, вы избегаете странного поведения, которое может возникнуть в результате передачи неверного строкового аргумента, который просто совпадает с именем несвязанного класса в текущей области.

4 голосов
/ 13 мая 2009

Если вам нужно использовать классы из отдаленных мест (и вообще-то, если вам вообще нужны какие-либо классы), то лучше всего создать и использовать для них словарь:

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)
1 голос
/ 13 мая 2009

Выбор объекта для создания не так сложно. Класс является объектом первого класса и может быть назначен переменной или передан в качестве аргумента функции.

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

Все работает хорошо, без особой боли. Вам не нужно что-то вроде "call_user_function" в Python

1 голос
/ 13 мая 2009

Для заданного объекта obj, заданного имени метода meth и заданного набора аргументов args:

    obj.__getattribute__(meth)(*args)

Должен доставить вас туда.

Конечно, само собой разумеется - какого чёрта ты хочешь делать?

0 голосов
/ 13 мая 2009

Вы можете вызвать getattr с localals () или globals (), чтобы сделать что-то похожее

# foo.method() is called if it's available in global scope
getattr(globals()['foo'], 'method')(*args)

# Same thing, but for 'foo' in local scope
getattr(locals()['foo'], 'method')(*args)

См. Также: Dive Into Python на getattr () , на localals () и globals ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...