2012-02-10 44 views
5

La idea básica de lo que quiero hacer es:¿Cómo tener diferentes tipos de entrada para la misma función?

def aFuncion(string = '', dicti = {}): 
    if len(str) > 0: 
     print 'you gave string as input' 
    if len(dicti) > 0: 
     print 'you gave a dict as input' 

aFunction(string = 'test') 
dict['test'] = test 
aFunction(dicti = dict) 

Sé que este tipo de idea que es posible en más de tipo OO de las lenguas, pero esto también es posible en Python?

En este momento estoy haciendo

def aFuncion(input): 
    if type(input) == str: 
     print 'you gave string as input' 
    if type(input) == dict: 
     print 'you gave a dict as input' 

aFunction('test') 

Pero quiero que la diferencia sea claro cuando se invoca la función

Respuesta

3

Este objetivo de querer que "la diferencia esté clara cuando se llama a la función" no concuerda tan bien con la filosofía de diseño del lenguaje. Google "pato escribiendo" para obtener más información al respecto. Las entradas aceptadas deben quedar claras mediante el docstring de la función, y eso es todo lo que necesita hacer.

En python, cuando quiere que su entrada sea una cadena o un dict, entonces simplemente escribe el código que asume que la entrada será un objeto que se comporta de forma similar a una cuerda o una forma similar a dict . Si la entrada no lo hace, entonces puede tratar de manejar eso con gracia, si lo desea, pero generalmente puede simplemente dejar su código para que aparezca con una excepción no controlada. Esto devuelve la pelota al tribunal de llamadas para decidir cómo manejar la situación o darse cuenta de que estaban enviando datos incorrectos.

En general, se deben evitar las comprobaciones de tipo, si es realmente necesario se debe hacer con isinstance en lugar de una verificación de igualdad del tipo como lo ha hecho. Esto tiene la ventaja de ser más flexible para las situaciones de herencia.

def aFuncion(input_): 
    if isinstance(input_, str): 
     print 'you gave a string-like input' 
    elif isinstance(input_, dict): 
     print 'you gave a dict-like input' 

aFunction('test') 

En python3 ahora tiene otra opción de utilizar las anotaciones de la función tipo de alusión. Lea PEP 484 para obtener más detalles sobre esa función.

+0

+1 Buen punto acerca de la filosofía del lenguaje. Además, creo que debería cambiar el nombre del argumento 'input' (ahora sobrescribe una función incorporada). – Tadeck

6

La idea de tener el mismo apoyo método de diferentes tipos de argumentos que se conoce como multiple dispatch or multimethods.

Para obtener una buena introducción, puede leer este Guido Van Rossum article y echar un vistazo a PyPi ya que hay unos pocos multimethod packages disponibles.

+0

Gracias, no sabía el nombre (estaba buscando polimorfismo) que debería ayudar –

0

Lo que básicamente funciona, solo hay algunos problemas con las declaraciones de variables. Aquí está una vesrion de trabajo:

def aFunction(str = '', dicti = {}): 
    if len(str) > 0: 
     print 'you gave string as input' 
    if len(dicti) > 0: 
     print 'you gave a dict as input' 

str = 'test' 
dicti = dict([('test', 'test')]) 
aFunction(str = str) 
aFunction(dicti = dicti) 
aFunction(str = str, dicti = dicti) 
aFunction(dicti = dicti, str = str) 

pone:

you gave string as input 
you gave a dict as input 
you gave string as input 
you gave a dict as input 
you gave string as input 
you gave a dict as input 

También puede tener argumentos no específicos que se envían a la función ya que tanto una lista y un diccionario (ver What is a clean, pythonic way to have multiple constructors in Python? por ejemplo).

+0

Su respuesta es incorrecta. Todavía puede llamar a 'aFunction' con:' aFunction ([1,2,3]) 'y asumirá que le dio una cadena (que claramente no es el caso), así como' aFunction (dicti = " esto no es un dict ")' y supondría que usted presentó una dict. @wim obtuvo la respuesta correcta, usando pato escribiendo. Asignar un argumento predeterminado a un tipo dado no le dará garantías, ya que Python es un lenguaje débilmente tipado y puede cambiar en el tiempo de ejecución. –

Cuestiones relacionadas