2010-10-26 38 views
33

Me pregunto si es mala manera omitir return None, cuando no es necesario.¿Está bien omitir "devolver ninguno"?

Ejemplo:

def foo1(x): 
    if [some condition]: 
     return Baz(x) 
    else: 
     return None 

def foo2(x): 
    if [some condition]: 
     return Baz(x) 

bar1 = foo1(x) 
bar2 = foo2(x) 

En ambos casos, cuando la condición es falsa, la función devolverá con None.

Respuesta

50

Como usted dijo, return None es (casi) nunca es necesario.

Pero debe tener en cuenta que la intención de su código es mucho más clara con un return None explícito. Recuerde: una parte del código también debe ser legible por los seres humanos, y ser explícito generalmente ayuda.

+1

También ayuda a "cumplir" con 'Import this': P –

+0

What aproximadamente al final de un método '__init__'? Como no puede 'devolver None', ¿es mejor tener' return' o nada en absoluto? – dln385

+0

@ dln385: puede 'devolver None' en' __init__', de hecho eso es lo que 'return' hace. – adw

4

Sí y No.

En el caso más simple, que está bien para saltar "return None" porque devuelve Ninguno sólo en condición negativa única.

Pero si hay una evaluación de condición anidada y múltiples escenarios donde una función podría devolver Ninguno. Tiendo a incluirlos como documentación visual de los escenarios.

[Edición: Basado en el comentario más abajo]

return or return None

prefiero "return None" al desnudo "retorno" ya que es explícita y más tarde, nadie va a estar en duda si el retorno significaba regresar Ninguno o fue un error ya que faltaba algo.

+0

Incluso con el anidamiento, puede usar 'return' en lugar de' return None'. A veces puede ser más claro hacer que el 'Ninguno' sea explícito, pero a menudo las personas usan' Ninguno' para indicar algún tipo de caso excepcional, en cuyo caso sería mejor plantear una excepción bien nombrada. – adw

+0

@adw: estoy de acuerdo contigo. Algunos de estos son hábitos de estilo. No me gusta usar solo "devolver" como si hubiera olvidado devolver algo. Prefiero "devolver ninguno" en tales casos, ya que soy explícito de que esto es lo que quería. – pyfunc

+0

Personalmente, no utilizo None por un valor excepcional, pero generalmente lo uso como marcador de posición para indicar el lugar por valor. [] o() luego indican un número indefinido de resultados y para algún tipo de funciones son mejores Valores falsos que return Ninguno (como None no iterable) –

2

Sí, si no devuelve ningún valor de una función de Python, devuelve None. Entonces, si devolver explícitamente None es una decisión estilística.

Personalmente, prefiero devolver siempre un valor para mayor claridad.

21

Para exponer lo que otros han dicho, utilizo un return None si se supone que la función devuelve un valor. En Python, todas las funciones devuelven un valor, pero a menudo escribimos funciones que solo devuelven None, porque su valor de retorno se ignora. En algunos idiomas, estos se llamarían procedimientos.

Así que si se supone que una función devuelve un valor, entonces me aseguro de que todas las rutas de código tengan un retorno, y que la devolución tenga un valor, incluso si es Ninguno.

Si una función "no" devuelve un valor, es decir, si nunca lo llama alguien utilizando su valor de retorno, entonces está bien terminar sin devolución, y si necesito regresar antes, utilizo la forma desnuda, return.

0
def foo1(x): 
    try: 
     return Baz(x) 
    except: 
     raise ValueError('Incorrect value fo Bac') 

o

def foo3(x): 
    return Baz(x) if <condition> else False 

Yo no creo en función de un medio definido, pero esta falsa puede ser útil en forma de buscar la poda fracaso.

0

Cuanto más lo pienso, menos creo que el caso que describe muestra buenas prácticas.Se obliga al cliente a discriminar, por lo que el código de cliente sería casi siempre ser:

b = foo1(123) 
if b is not None: 
    ... 

Ni siquiera se podría escribir:

if b: 
    ... 

ya que, si se sobrescribe Baz.__nonzero__, b podría evaluar en False, incluso si no es ninguno. Sería mejor tener un Null-Baz instancia (También conocido como Null Object), ej .:

class Baz(object): 
    def some_method(self): 
     """some action:""" 
     ... 
    ... 

class BazNull(Baz): 
    def some_method(self): 
     """nothing happens here""" 
    ... 

Baz.Null = BazNull() 

... 

def foo1(x): 
    if some_condition: 
     return Baz(x) 
    else: 
     return Baz.Null 

... 

b = foo1(123) 
b.some_method() 

El punto es: (¿quién podría ser usted mismo) ayudar al cliente a mantener Cyclomatic Complexity baja. Cuantas menos ramas, mejor.

+0

Buen punto. Pero en algunos casos me veo obligado a devolver None. Es decir. en Django Middleware, devolverá None en la mayoría de sus métodos. –

+0

Bajé la votación porque incluso si la sugerencia es válida en algunos casos, está fuera del alcance de la pregunta. – ehabkost

Cuestiones relacionadas