2011-03-08 22 views
10

En Ruby si tengo un objeto obj, con un método llamado funcname, puedo llamar el método que utiliza la siguiente sintaxis obj.send (funcname)Equivalente de rubí obj.send en Python

¿Existe algo parecido en python.

La razón por la que quiero hacer esto es que tengo una instrucción switch donde establezco el nombre de func y quiero llamarlo al final de la instrucción switch.

+2

Python doesn' t tiene una declaración de cambio. Además, generar nombres de funciones en tiempo de ejecución es casi siempre una mala idea. –

+1

@Rafe: no es comúnmente necesario, pero no tiene nada de intrínsecamente malo. –

+0

Sí, no, pero aún quiero hacerlo en y si-elif-else loop. Creo que recibí mi respuesta a continuación. –

Respuesta

19
getattr(obj, "name")(args) 

9

hmmm ... getattr (obj, funcname) (* args, ** kwargs)?

>>> s = "Abc" 

>>> s.upper() 
'ABC' 

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

>>> getattr(s, "lower")() 
'abc' 
1

Aparte de la ya mencionada getattr() orden interna:

Como alternativa a un if-elif-else bucle puede utilizar un diccionario para mapear sus "casos" a las funciones/métodos deseados:

# 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 

métodos relativos en lugar de las funciones de civil:

  • que sólo puede convertir el citado correo jemplo en method_dict usando, por ejemplo, en lugar de lambda obj: obj.method_a()function_a etc., y luego hacer method_dict[case](obj)
  • puede utilizar getattr() como otras respuestas ya han mencionado, pero sólo se necesita si realmente necesita para obtener el método de su nombre.
  • operator.methodcaller() de stdlib es un buen atajo en algunos casos: basado en un nombre de método y opcionalmente algunos argumentos, crea una función que llama al método con ese nombre en otro objeto (y si proporcionó argumentos adicionales al crear la methodcaller, se llama al método con estos argumentos)
1

O, si lo prefiere, operator.methodcaller('foo') es una función que llama foo en lo que se pasa. En otras palabras,

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

es equivalente a

bar.foo() 

(creo que esto es probablemente el adjunto o doble en una categoría adecuada. Si usted es matemáticamente inclinado.)