Эквивалент ruby ​​obj.send в python - PullRequest
10 голосов
/ 09 марта 2011

В ruby, если у меня есть объект obj, с методом funcname, я могу вызвать метод, используя следующий синтаксис obj.send (funcname)

Есть ли что-то подобное в python.1004 * Причина, по которой я хочу это сделать, в том, что у меня есть оператор switch, в котором я установил funcname и хочу вызвать его в конце оператора switch.

Ответы [ 4 ]

19 голосов
/ 09 марта 2011
getattr(obj, "name")(args)

1002 *

9 голосов
/ 09 марта 2011

хммм ... getattr (obj, funcname) (* args, ** kwargs)?

>>> s = "Abc"

>>> s.upper()
'ABC'

>>> getattr(s, "upper")()
'ABC'

>>> getattr(s, "lower")()
'abc'
1 голос
/ 09 марта 2011

Или, если хотите, operator.methodcaller('foo') - это функция, которая вызывает foo для всего, что вы передаете.Другими словами,

import operator
fooer = operator.methodcaller("foo")
fooer(bar)

эквивалентно

bar.foo()

(я думаю, что это, вероятно, сопряженное или двойственное в подходящей категории. Если вы склонны математически.)

1 голос
/ 09 марта 2011

Помимо уже упомянутого getattr() встроенного:

В качестве альтернативы циклу if-elif-else вы можете использовать словарь, чтобы сопоставить ваши "дела" с желаемыми функциями / методами:

# given func_a, func_b and func_default already defined
function_dict = {
    'a': func_a,
    'b': func_b  
}
x = 'a'
function_dict(x)() # -> func_a()
function_dict.get('xyzzy', func_default)() # fallback to -> func_c

Относительно методов вместо простых функций:

  • Вы можете просто превратить приведенный выше пример в method_dict, используя, например, lambda obj: obj.method_a() вместо function_a и т. Д., А затем выполнить method_dict[case](obj)
  • вы можете использовать getattr(), как уже упоминалось в других ответах, но он вам нужен только в том случае, если вам действительно нужно получить метод из его имени.
  • operator.methodcaller () из stdlib - это хороший ярлык в некоторых случаях: на основе имени метода и, необязательно, некоторых аргументов, он создает функцию, которая вызывает метод с этим именем для другого объекта (и если вы указали какие-либо дополнительные аргументы при создании метода, он вызовет метод с этими аргументами)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...