2011-05-13 5 views
13

Tengo un método que actualmente devuelve None o dict.¿Debo devolver un dict vacío en lugar de None?

result,error = o.apply('grammar') 

La persona que llama actualmente tiene que verificar la existencia de dos claves para decidir qué tipo de objeto se devolvió.

if 'imperial' in result: 
    # yay 
elif 'west' in result: 
    # yahoo 
else: 
    # something wrong? 

Debido resultado puede ser None, estoy pensando en devolver un dict vacía en su lugar, por lo que la persona que llama no necesita comprobar para eso. Qué piensas ?

En comparación, en el módulo re, el resultado de llamar match puede resultar en None.

p = re.compile('\w+') 
m = p.match('whatever') 

Pero en este caso, m es una instancia de objeto. En mi caso, estoy devolviendo un dict que debería estar vacío o tener algunas entradas.

+0

Realmente siento que la interfaz 'p.match' está ligeramente rota en este sentido. Me gustaría que devolviera un objeto de evaluación "falso" en lugar de 'ninguno'. – Omnifarious

Respuesta

18

Sí, creo que es preferible devolver un dict vacío (o, en su caso, una lista vacía) a None, ya que esto evita una verificación adicional en el código del cliente.

EDIT: Agregando un poco de ejemplo de código para elaborar:

def result_none(choice): 
    mydict = {} 
    if choice == 'a': 
     mydict['x'] = 100 
     mydict['y'] = 1000 
     return mydict 
    else: 
     return None 

def result_dict(choice): 
    mydict = {} 
    if choice == 'a': 
     mydict['x'] = 100 
     mydict['y'] = 1000 
    return mydict 

test_dict = result_dict('b') 
if test_dict.get('x'): 
    print 'Got x' 
else: 
    print 'No x' 

test_none = result_none('b') 
if test_none.get('x'): 
    print 'Got x' 
else: 
    print 'No x' 

En el código anterior el cheque test_none.get(x) lanza un método como result_none AttributeError posiblemente puede devolver un Ninguno. Para evitar eso, tengo que agregar una verificación adicional y podría reescribir esa línea como: if test_none is not None and test_none.get('x'), que no es en absoluto necesario si el método devolvía un dict vacío. Como muestra el ejemplo, el cheque test_dict.get('x') funciona bien ya que el método result_dict devuelve un dict vacío.

+0

Estoy de acuerdo. El único momento en que se debe devolver 'None' en estos casos es si hay algún significado más allá de 'no respuestas' que deba transmitirse. – Omnifarious

+0

Parece que se olvidó de devolver el dict de 'result_none' (aunque realmente no afecta el comportamiento de su ejemplo). –

+0

@Josh gracias. Arreglado. – sateesh

3

Después de pensar más, creo que devolver un dict vacío podría ser más pitónico. Una buena regla general podría ser devolver siempre un contenedor vacío si escribe una función/método que devuelve un contenedor. Varios ejemplos de este comportamiento:

"".split() == [] 
filter(lambda a:False, [1,2]) == [] 
range(1, -1) == [] 
re.findall('x', '') = [] 

Por el contrario, si usted está tratando de obtener un único objeto, que no tienen más remedio que volver None supongo. ¡Así que supongo que None es como el contenedor vacío para objetos individuales! Gracias a KennyTM por argumentar algo de sentido común en mí: D

+0

'.get' no" devuelve "un' dict' aquí. – kennytm

+0

Sí devuelve un valor o None de forma predeterminada. – zeekay

+0

@zeekay: No, quiero decir '{'a': 1} .get ('a')' devuelve '1', no es un dict. Además, observe que 'None.get ('b')' es un error, lo que sugiere que 'None' should * not * debe ser devuelto en el código de OP :). – kennytm

2

Como han dicho otros, un dict vacío es falso, por lo que no hay ningún problema allí. Pero la idea de devolver un dict vacío me deja un mal sabor de boca. No puedo evitar sentir que devolver un dict vacío podría ocultar los errores que revelaría None. Aún así, es solo una corazonada.

+3

Preferiría devolver un diccionario vacío a menos que 'None' y' {} 'realmente signifiquen cosas diferentes, en cuyo caso, probablemente usaría una excepción de todos modos. –

4

No estoy del todo seguro del contexto de este código, pero diría que al regresar Ninguno sugiere que hubo algún error y que la operación no se pudo completar. Devolver un diccionario vacío sugiere éxito, pero nada coincide con los criterios para ser agregado al diccionario.

Vengo de un fondo completamente diferente (C++ desarrollo del juego) para dar esto por lo que vale la pena:

Por motivos de rendimiento, sin embargo, podría ser agradable volver Ninguno y salvar lo de arriba, aunque mínimo, pueden estar involucrados en crear un diccionario vacío En general, considero que si usa un lenguaje de scripting, no le preocupa el rendimiento de ese código. Si lo fuera, probablemente no estaría escribiendo esa característica en dicho idioma a menos que sea necesario por alguna razón inevitable.

+1

Probablemente arrojaré una excepción si se encuentra un error (como opuesto a devolver None). Creo que ese es el camino pitónico. –

Cuestiones relacionadas