¿Cómo usar la declaración “aprobar”?

11 minutos de lectura

Avatar de usuario de Capurnicus
capurnico

Estoy en el proceso de aprender Python y he llegado a la sección sobre el pass declaración. La guía que estoy usando lo define como una declaración nula que se usa comúnmente como marcador de posición.

Aunque todavía no entiendo completamente lo que eso significa. ¿Cuál sería una situación simple/básica en la que el pass se usaría la declaración y por qué sería necesaria?

  • Nunca he necesitado hacer esto en la vida real, pero podría suponer pass sería útil cuando desee anular un método en una subclase para que no haga nada.

    – kojiro

    24 de marzo de 2014 a las 14:22

  • @kojiro, por ejemplo, a veces es útil al hacer en.wikipedia.org/wiki/Skeleton_(programación_computadora)

    – Franck Dernoncourt

    29 de agosto de 2015 a las 21:54

  • Muy útil cuando se procesan excepciones. A veces, una excepción significa una condición normal que solo requiere un tipo diferente de procesamiento. En ese caso pass en el except bloque viene muy bien.

    – Físico loco

    4 de enero de 2016 a las 14:01

avatar de usuario de sebastian_oe
sebastian_oe

Suponga que está diseñando una nueva clase con algunos métodos que aún no desea implementar.

class MyClass(object):
    def meth_a(self):
        pass

    def meth_b(self):
        print "I'm meth_b"

Si tuviera que dejar de lado el passel código no se ejecutaría.

Entonces obtendrías un:

IndentationError: expected an indented block

Para resumir, el pass declaración no hace nada en particular, pero puede actuar como marcador de posición, como se demuestra aquí.

  • Bueno, en este caso también se podría usar returnaunque con una ligera pérdida de claridad.

    usuario395760

    14 de diciembre de 2012 a las 21:27

  • Realmente no creo que esto responda adecuadamente a la pregunta. Citar un posible uso de algo, aunque sea el más común, no es lo mismo que explicar para qué sirve.

    – Schilcote

    15/03/2014 a las 17:47

  • @Schilcote: veo tu punto. Agregué otra breve explicación a mi respuesta inicial. Sin embargo, creo que un ejemplo simple muchas veces ayuda a entender un concepto determinado.

    – sebastian_oe

    15/03/2014 a las 19:11

  • La respuesta de @Anaphory, a continuación, muestra por qué este es un elemento de lenguaje importante.

    – John

    7 julio 2016 a las 19:52


  • Esto explica un uso de pass, pero todavía no entiendo realmente lo que hace. ¿Hay un uso para esto en el código de producción? De su ejemplo, optaría por no agregar ese método hasta que esté listo para implementarlo, o simplemente haría return.

    – el otro lado

    28/08/2018 a las 20:00

Avatar de usuario de Anaphory
Anaforia

Python tiene el requisito sintáctico de que el código bloquee (después de if, except, def, class etc.) no puede estar vacío. Sin embargo, los bloques de código vacíos son útiles en una variedad de contextos diferentes, como en los ejemplos a continuación, que son los casos de uso más frecuentes que he visto.

Por lo tanto, si no se supone que suceda nada en un bloque de código, un pass es necesario para que dicho bloque no produzca un IndentationError. Alternativamente, cualquier declaración (incluyendo sólo un término para ser evaluado, como el Ellipsis literal ... o una cadena, más a menudo una cadena de documentos), pero el pass deja en claro que, de hecho, no se supone que suceda nada, y no necesita ser evaluado y (al menos temporalmente) almacenado en la memoria.

  • Ignorar (todas o) cierto tipo de Exception (ejemplo de xml):

     try:
         self.version = "Expat %d.%d.%d" % expat.version_info
     except AttributeError:
         pass # unknown
    

    Nota: Ignorando todos los tipos de aumentos, como en el siguiente ejemplo de pandasgeneralmente se considera una mala práctica, porque también detecta excepciones que probablemente deberían pasarse a la persona que llama, por ejemplo KeyboardInterrupt o SystemExit (o incluso HardwareIsOnFireError – ¿Cómo sabe que no se está ejecutando en un cuadro personalizado con errores específicos definidos, que alguna aplicación de llamada querría saber?).

     try:
         os.unlink(filename_larry)
     except:
         pass
    

    En lugar de usar al menos except Error: o en este caso preferiblemente except OSError: se considera una práctica mucho mejor. Un análisis rápido de todos los módulos de Python que he instalado me dio que más del 10% de todos except ...: pass Las declaraciones capturan todas las excepciones, por lo que sigue siendo un patrón frecuente en la programación de Python.

  • Derivar una clase de excepción que no agregue un nuevo comportamiento (por ejemplo, en SciPy):

     class CompileError(Exception):
         pass
    

    De manera similar, las clases pensadas como clases base abstractas a menudo tienen un vacío explícito. __init__ u otros métodos que se supone que derivan las subclases (p. ej., pebl):

     class _BaseSubmittingController(_BaseController):
         def submit(self, tasks): pass
         def retrieve(self, deferred_results): pass
    
  • Probar ese código se ejecuta correctamente para algunos valores de prueba, sin preocuparse por los resultados (desde mpmath):

     for x, error in MDNewton(mp, f, (1,-2), verbose=0,
                              norm=lambda x: norm(x, inf)):
         pass
    
  • En las definiciones de clases o funciones, a menudo ya existe una cadena de documentación como declaración obligatoria para ser ejecutado como lo único en el bloque. En tales casos, el bloque puede contener pass además a la cadena de documentación para decir “Esto de hecho tiene la intención de no hacer nada”, por ejemplo en pebl:

     class ParsingError(Exception):
         """Error encountered while parsing an ill-formed datafile."""
         pass
    
  • En algunos casos, pass se utiliza como marcador de posición para decir “Este método/clase/si-bloque/… aún no se ha implementado, pero este será el lugar para hacerlo”, aunque personalmente prefiero el Ellipsis literal ... para diferenciar estrictamente entre esto y el “no-op” intencional en el ejemplo anterior. (Tenga en cuenta que el literal Ellipsis es una expresión válida solo en Python 3)

    Por ejemplo, si escribo un modelo a grandes rasgos, podría escribir

     def update_agent(agent):
         ...
    

    donde otros podrían tener

     def update_agent(agent):
         pass
    

    antes de

     def time_step(agents):
         for agent in agents:
             update_agent(agent)
    

    como un recordatorio para completar el update_agent funcione en un punto posterior, pero ejecute algunas pruebas para ver si el resto del código se comporta como se esperaba. (Una tercera opción para este caso es raise NotImplementedError. Esto es útil en particular para dos casos: O bien “Este método abstracto debe ser implementado por cada subclase, y no hay una forma genérica de definirlo en esta clase base”o “Esta función, con este nombre, aún no está implementada en esta versión, pero así se verá su firma”)

Avatar de usuario de Micah Walter
miqueas walter

Además de su uso como marcador de posición para funciones no implementadas, pass puede ser útil para completar una declaración if-else (“Explícito es mejor que implícito”).

def some_silly_transform(n):
    # Even numbers should be divided by 2
    if n % 2 == 0:
        n /= 2
        flag = True
    # Negative odd numbers should return their absolute value
    elif n < 0:
        n = -n
        flag = True
    # Otherwise, number should remain unchanged
    else:
        pass

Por supuesto, en este caso, uno probablemente usaría return en lugar de asignación, pero en los casos en que se desea la mutación, esto funciona mejor.

El uso de pass aquí es especialmente útil para advertir a los futuros mantenedores (¡incluido usted mismo!) que no coloquen pasos redundantes fuera de las declaraciones condicionales. En el ejemplo anterior, flag se establece en los dos casos específicamente mencionados, pero no en el else-caso. Sin uso passun futuro programador podría moverse flag = True a fuera de la condición, estableciendo así flag en todos casos.


Otro caso es con la función repetitiva que a menudo se ve en la parte inferior de un archivo:

if __name__ == "__main__":
    pass

En algunos archivos, sería bueno dejar eso allí con pass para permitir una edición posterior más sencilla y para dejar explícito que no se espera que suceda nada cuando el archivo se ejecuta por sí solo.


Finalmente, como se menciona en otras respuestas, puede ser útil no hacer nada cuando se detecta una excepción:

try:
    n[i] = 0
except IndexError:
    pass

  • Creo que los dos primeros ejemplos son generalmente malas prácticas. Con respecto al primer ejemplo, debe configurar flag = False antes de if ... elif bloque para evitar errores oscuros “NameError: el nombre ‘bandera’ no está definido” más adelante. Con respecto al segundo ejemplo, parece bizzar tener que agregar if __name__ == "__main__": pass a la mayoría de los archivos de Python que no hacen nada cuando se ejecutan directamente (que es el caso cuando está escribiendo código modular). Con Python >= 3.0, deberías usar ... (puntos suspensivos) en lugar de pass para indicar bloques “terminar más tarde”.

    – ostrokach

    19 de junio de 2017 a las 7:29


  • Si toda la cláusula else pasa, es decir, no hace nada, ¿entonces por qué molestarse en incluirla?

    – Matemáticas de la jungla

    10 de febrero a las 17:25


  • @Junglemath Es posible que desee dejar en claro a los desarrolladores posteriores que hay otras condiciones que deben completarse, además de las enumeradas. En general, explícito es mejor que implícito, y esta es una forma de decir explícitamente “No he enumerado todas las condiciones; hay otras, para las cuales la funcionalidad actual es no hacer nada, aunque puede que no siempre sea así. “

    – Miqueas Walter

    11 de febrero a las 18:11

La mejor y más precisa manera de pensar en pass es como una forma de decirle explícitamente al intérprete que no haga nada. De la misma manera el siguiente código:

def foo(x,y):
    return x+y

significa “si llamo a la función foo(x, y), sumo los dos números que representan las etiquetas x e y y devuelvo el resultado”,

def bar():
    pass

significa “Si llamo a la función bar(), no hago absolutamente nada”.

Las otras respuestas son bastante correctas, pero también es útil para algunas cosas que no implican ocupar un lugar.

Por ejemplo, en un fragmento de código en el que trabajé recientemente, era necesario dividir dos variables y era posible que el divisor fuera cero.

c = a / b

obviamente, producirá un ZeroDivisionError si b es cero. En esta situación particular, dejar c como cero era el comportamiento deseado en el caso de que b fuera cero, así que usé el siguiente código:

try:
    c = a / b
except ZeroDivisionError:
    pass

Otro uso menos estándar es como un lugar práctico para colocar un punto de interrupción para su depurador. Por ejemplo, quería que un poco de código entrara en el depurador en la iteración 20 de una instrucción for… in. Asi que:

for t in range(25):
    do_a_thing
    if t == 20:
        pass

con el punto de quiebre en el pase.

Un caso de uso común en el que se puede usar ‘tal cual’ es anular una clase solo para crear un tipo (que por lo demás es lo mismo que la superclase), por ejemplo

class Error(Exception):
    pass

Para que puedas subir y atrapar Error excepciones Lo que importa aquí es el tipo de excepción, más que el contenido.

Avatar de usuario de Peter Mortensen
Pedro Mortensen

pass en Python básicamente no hace nada, pero a diferencia de un comentario, el intérprete no lo ignora. Por lo tanto, puede aprovecharlo en muchos lugares al convertirlo en un marcador de lugar:

1: se puede usar en clase

class TestClass:
    pass

2: Se puede usar en sentencias de bucle y condicionales:

if (something == true):  # used in conditional statement
    pass

while (some condition is true):  # user is not sure about the body of the loop
    pass

3: se puede utilizar en la función:

def testFunction(args): # The programmer wants to implement the body of the function later
    pass

pass se usa principalmente cuando el programador no quiere dar implementación en este momento, pero todavía quiere crear una determinada clase/función/sentencia condicional que se puede usar más adelante. Dado que el intérprete de Python no permite una clase, función o declaración condicional en blanco o no implementada, da un error:

Error Tabulación: Se esperaba un bloque tabulado

pass se puede utilizar en tales escenarios.

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Puedes decir eso aprobar significa un NOP (sin operación) operación. Obtendrá una imagen clara después de este ejemplo:

Programa C

#include<stdio.h>

void main()
{
    int age = 12;
  
    if( age < 18 )
    {
         printf("You are not adult, so you can't do that task ");
    }
    else if( age >= 18 && age < 60)
    {
        // I will add more code later inside it 
    }
    else
    {
         printf("You are too old to do anything , sorry ");
    }
}

Ahora, cómo escribirás eso en Python:

age = 12

if age < 18:

    print "You are not adult, so you can't do that task"

elif age >= 18 and age < 60:

else:

    print "You are too old to do anything , sorry "

Pero su código dará un error porque requería un bloque sangrado después elif. Aquí está el papel del aprobar palabra clave.

age = 12

if age < 18:

    print "You are not adult, so you can't do that task"

elif age >= 18 and age < 60:
    
    pass

else:

    print "You are too old to do anything , sorry "

Ahora creo que lo tienes claro.

¿Ha sido útil esta solución?