2010-11-09 23 views
16

Hace algunos días estaba buscando en la red y encontré un artículo interesante sobre los diccionarios de Python. Se trataba de usar las teclas en el diccionario para llamar a una función. En ese artículo, el autor ha definido algunas funciones, y luego un diccionario con la clave exactamente igual que el nombre de la función. Luego pudo obtener un parámetro de entrada del usuario y llamar al mismo método (algo así como implementar la interrupción de caso) Después de eso me di cuenta de lo mismo pero de alguna manera diferente. Quiero saber cómo puedo implementar esto. si tengo una función:Usar una cadena para llamar a la función en Python

def fullName(name = "noName", family = "noFamily"): 
    return name += family 

Y ahora si tengo una cadena como esta:

myString = "fullName(name = 'Joe', family = 'Brand')" 

¿Hay una manera de ejecutar esta consulta y obtener un resultado: JoeBrand
Por ejemplo algo Recuerdo que podríamos dar una cadena a la declaración exec() y lo hace por nosotros. Pero no estoy seguro acerca de este caso especial, y tampoco conozco la manera eficiente en Python. Y también estaré muy agradecido de ayudarme a manejar el valor de devolución de las funciones, por ejemplo, en mi caso, ¿cómo puedo imprimir el nombre completo devuelto por esa función?

+2

funcionas va retorno Ninguno ... + uso en lugar de + = – Ant

+1

Para lograr esto, el uso: getattr (miCadena, 'fullName') (name = 'Joe', family = 'Brand') [vea la pregunta duplicada vinculada al principio de la página] – Stew

+0

[Nota: getattr() es usado por la respuesta principal en la pregunta que esta publicación duplica, pero no se menciona a continuación. Pensé que sería útil aparecer en esta página, por lo que rechazo la convención para responder preguntas en los comentarios.] – Stew

Respuesta

26

Usted podría utilizar eval():

myString = "fullName(name = 'Joe', family = 'Brand')" 
result = eval(myString) 

Sin embargo, Aviso, se considera eval() mal por muchas personas.

+0

Gracias de antemano, pero ¿devuelve algún valor de la función en caso de que la almacene en una variable? – user435245

+0

Sí, lo hace. Ver mi respuesta actualizada. –

+2

Mejor respuesta: http: // stackoverflow.com/questions/3061/calling-a-function-from-a-string-with-the-functions-name-in-python – Framester

37

Esto no responde exactamente a su pregunta, pero tal vez esto ayuda, sin embargo:

Como se ha mencionado, eval se debe evitar si es posible. Una mejor manera de usar el diccionario es desempacar el diccionario. Esto también es muy dinámico y menos propenso a errores.

Ejemplo:

def fullName(name = "noName", family = "noFamily"): 
    return name + family 

functionList = {'fullName': fullName} 

function = 'fullName' 
parameters = {'name': 'Foo', 'family': 'Bar'} 

print functionList[function](**parameters) 
# prints FooBar 

parameters = {'name': 'Foo'} 
print functionList[function](**parameters) 
# prints FoonoFamily 
+3

+1 por no sugerir 'eval' – MAK

6

Sé que esta pregunta es bastante antiguo, pero se puede hacer algo como esto:

argsdict = {'name': 'Joe', 'family': 'Brand'} 
globals()['fullName'](**argsdict) 

argsdict es un diccionario de argumentos globals, llama a la función mediante una cadena y ** amplía el diccionario a una lista de parámetros. Mucho más limpio que eval. El único problema está en dividir la cuerda. Una solución (muy sucio):

example = 'fullName(name=\'Joe\',family=\'Brand\')' 
# Split at left parenthesis 
funcname, argsstr = example.split('(') 
# Split the parameters 
argsindex = argsstr.split(',') 
# Create an empty dictionary 
argsdict = dict() 
# Remove the closing parenthesis 
# Could probably be done better with re... 
argsindex[-1] = argsindex[-1].replace(')', '') 
for item in argsindex: 
    # Separate the parameter name and value 
    argname, argvalue = item.split('=') 
    # Add it to the dictionary 
    argsdict.update({argname: argvalue}) 
# Call our function 
globals()[funcname](**argsdict) 
+0

La única solución. Si este código reside en un módulo, y ese módulo se volvería a cargar después de que se cambiara el código de 'fullName', entonces los cambios entrarán en vigencia en la siguiente llamada a' fullName'. La respuesta de Felix Kling no tiene esta propiedad ya que la función está en caché en 'functionList', y ni siquiera hablaremos de cuán mala es la idea' eval'. –

Cuestiones relacionadas