Python: как вы вызываете метод, когда у вас есть только имя строки метода?
Это используется для использования в JSON API.
Я не хочу иметь:
if method_str == 'method_1':
method_1()
if method_str == 'method_2':
method_2()
По понятным причинам это не оптимально. Как я могу использовать строки карт для таких методов в многоразовом виде (также обратите внимание, что мне нужно передать аргументы вызываемым функциям).
Вот пример:
ВХОДЯЩИЙ JSON:
{
'method': 'say_something',
'args': [
135487,
'a_465cc1'
]
'kwargs': {
'message': 'Hello World',
'volume': 'Loud'
}
}
# JSON would be turned into Python with Python built in json module.
Результирующий вызов:
# Either this
say_something(135487, 'a_465cc1', message='Hello World', volume='Loud')
# Or this (this is more preferable of course)
say_something(*args, **kwargs)
Ответы
Ответ 1
Для методов экземпляров используйте getattr
>>> class MyClass(object):
... def sayhello(self):
... print "Hello World!"
...
>>> m=MyClass()
>>> getattr(m,"sayhello")()
Hello World!
>>>
Для функций вы можете посмотреть в глобальном dict
>>> def sayhello():
... print "Hello World!"
...
>>> globals().get("sayhello")()
Hello World!
В этом случае, поскольку функция prove_riemann_hypothesis
отсутствует, используется функция по умолчанию (sayhello
)
>>> globals().get("prove_riemann_hypothesis", sayhello)()
Hello World!
Проблема с этим подходом заключается в том, что вы используете пространство имен с любым другим содержимым. Возможно, вы захотите защитить от методов вызова json, которые не предполагается. Хороший способ сделать это - украсить ваши функции следующим образом
>>> json_functions={}
>>> def make_available_to_json(f):
... json_functions[f.__name__]=f
... return f
...
>>> @make_available_to_json
... def sayhello():
... print "Hello World!"
...
>>> json_functions.get("sayhello")()
Hello World!
>>> json_functions["sayhello"]()
Hello World!
>>> json_functions.get("prove_riemann_hypothesis", sayhello)()
Hello World!
Ответ 2
Использовать getattr.
Например:
class Test(object):
def say_hello(self):
print 'Hell no, world!!111'
def test(self):
getattr(self, 'say_hello')()
Ответ 3
Чистый, безопасный способ сделать это - сделать имена имен символов для функций. Если это на самом деле методы, лучшим способом все же является такой тип, хотя getattr
также доступен. Использование globals
или eval
небезопасно и грязно.
Ответ 4
Предполагая, что все функции являются глобальными (они есть, если они не определены внутри других функций), к ним можно получить доступ с помощью функции globals()
. globals()
возвращает словарь всех глобальных переменных, включая функции.
Например:
$ python
Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def some_function():
... print "Hello World!"
...
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'some_function': <function some_function at 0x6326b0>, '__package__': None}
>>> globals()['some_function']()
Hello World!