8. Sentencias compuestas
************************

Las sentencias compuestas contienen (grupos de) otras sentencias;
estas afectan o controlan la ejecución de esas otras sentencias de
alguna manera. En general, las sentencias compuestas abarcan varias
líneas, aunque en representaciones simples una sentencia compuesta
completa puede estar contenida en una línea.

Las sentencias "if", "while" y "for" implementan construcciones de
control de flujo tradicionales. "try" especifica gestores de excepción
o código de limpieza para un grupo de sentencias, mientras que las
sentencias "with" permite la ejecución del código de inicialización y
finalización alrededor de un bloque de código. Las definiciones de
función y clase también son sentencias sintácticamente compuestas.

Una sentencia compuesta consta de una o más 'cláusulas'. Una cláusula
consta de un encabezado y una 'suite'. Los encabezados de cláusula de
una declaración compuesta particular están todos en el mismo nivel de
indentación. Cada encabezado de cláusula comienza con una palabra
clave de identificación única y termina con dos puntos. Una suite es
un grupo de sentencias controladas por una cláusula. Una suite puede
ser una o más sentencias simples separadas por punto y coma en la
misma línea como el encabezado, siguiendo los dos puntos del
encabezado, o puede ser una o puede ser una o más declaraciones
indentadas en líneas posteriores. Solo la última forma de una suite
puede contener sentencias compuestas anidadas; lo siguiente es ilegal,
principalmente porque no estaría claro a qué cláusula "if" seguido de
la cláusula "else" hace referencia:

   if test1: if test2: print(x)

También tenga en cuenta que el punto y coma se une más apretado que
los dos puntos en este contexto, de modo que en el siguiente ejemplo,
todas o ninguna de las llamadas "print()" se ejecutan:

   if x < y < z: print(x); print(y); print(z)

Resumiendo:

   compound_stmt ::= if_stmt
                     | while_stmt
                     | for_stmt
                     | try_stmt
                     | with_stmt
                     | funcdef
                     | classdef
                     | async_with_stmt
                     | async_for_stmt
                     | async_funcdef
   suite         ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
   statement     ::= stmt_list NEWLINE | compound_stmt
   stmt_list     ::= simple_stmt (";" simple_stmt)* [";"]

Tenga en cuenta que las sentencias siempre terminan en un "NEWLINE"
posiblemente seguida de "DEDENT". También tenga en cuenta que las
cláusulas de continuación opcionales siempre comienzan con una palabra
clave que no puede iniciar una sentencia, por lo tanto, no hay
ambigüedades (el problema de 'colgado "if"' se resuelve en Python al
requerir que las sentencias anidadas "if" deben estar indentadas).

El formato de las reglas gramaticales en las siguientes secciones
coloca cada cláusula en una línea separada para mayor claridad.


8.1. La sentencia "if"
======================

La sentencia "if" se usa para la ejecución condicional:

   if_stmt ::= "if" assignment_expression ":" suite
               ("elif" assignment_expression ":" suite)*
               ["else" ":" suite]

Selecciona exactamente una de las suites evaluando las expresiones una
por una hasta que se encuentre una verdadera (vea la sección
Operaciones booleanas para la definición de verdadero y falso);
entonces esa suite se ejecuta (y ninguna otra parte de la sentencia
"if" se ejecuta o evalúa). Si todas las expresiones son falsas, se
ejecuta la suite de cláusulas "else", si está presente.


8.2. La sentencia "while"
=========================

La sentencia "while" se usa para la ejecución repetida siempre que una
expresión sea verdadera:

   while_stmt ::= "while" assignment_expression ":" suite
                  ["else" ":" suite]

Esto prueba repetidamente la expresión y, si es verdadera, ejecuta la
primera suite; si la expresión es falsa (que puede ser la primera vez
que se prueba), se ejecuta el conjunto de cláusulas "else", si está
presente, y el bucle termina.

La sentencia "break" ejecutada en la primer suite termina el bucle sin
ejecutar la suite de cláusulas "else". La sentencia "continue"
ejecutada en la primera suite omite el resto de la suite y vuelve a
probar la expresión.


8.3. La sentencia "for"
=======================

La sentencia "for" se usa para iterar sobre los elementos de una
secuencia (como una cadena de caracteres, tupla o lista) u otro objeto
iterable:

   for_stmt ::= "for" target_list "in" expression_list ":" suite
                ["else" ":" suite]

La lista de expresiones se evalúa una vez; debería producir un objeto
iterable. Se crea un iterador para el resultado de la
"expression_list". La suite se ejecuta una vez para cada elemento
proporcionado por el iterador, en el orden retornado por el iterador.
Cada elemento a su vez se asigna a la lista utilizando las reglas
estándar para las asignaciones (ver Declaraciones de asignación), y
luego se ejecuta la suite. Cuando los elementos están agotados (que es
inmediatamente cuando la secuencia está vacía o un iterador genera una
excepción del tipo "StopIteration"), la suite en la cláusula "else",
si está presente, se ejecuta y el bucle termina.

La sentencia "break" ejecutada en la primera suite termina el bucle
sin ejecutar el conjunto de cláusulas "else". La sentencia "continue"
ejecutada en la primera suite omite el resto de las cláusulas y
continúa con el siguiente elemento, o con la cláusula "else" si no hay
un elemento siguiente.

El bucle "for" realiza asignaciones a las variables en la lista. Esto
sobrescribe todas las asignaciones anteriores a esas variables,
incluidas las realizadas en la suite del bucle "for":

   for i in range(10):
       print(i)
       i = 5             # this will not affect the for-loop
                         # because i will be overwritten with the next
                         # index in the range

Los nombres en la lista no se eliminan cuando finaliza el bucle, pero
si la secuencia está vacía, el bucle no les habrá asignado nada.
Sugerencia: la función incorporada "range()" retorna un iterador de
enteros adecuado para emular el efecto de Pascal "for i := a to b do";
por ejemplo, "list(range(3))" retorna la lista "[0, 1, 2]".

Nota:

  Hay una sutileza cuando la secuencia está siendo modificada por el
  bucle (esto solo puede ocurrir para secuencias mutables, por
  ejemplo, listas). Se utiliza un contador interno para realizar un
  seguimiento de qué elemento se usa a continuación, y esto se
  incrementa en cada iteración. Cuando este contador ha alcanzado la
  longitud de la secuencia, el bucle termina. Esto significa que si la
  suite elimina el elemento actual (o anterior) de la secuencia, se
  omitirá el siguiente elemento (ya que obtiene el índice del elemento
  actual que ya ha sido tratado). Del mismo modo, si la suite inserta
  un elemento en la secuencia anterior al elemento actual, el elemento
  actual será tratado nuevamente la próxima vez a través del bucle.
  Esto puede conducir a errores graves que se pueden evitar haciendo
  una copia temporal usando una porción de la secuencia completa, por
  ejemplo,

     for x in a[:]:
         if x < 0: a.remove(x)


8.4. La sentencia "try"
=======================

La sentencia "try" es especifica para gestionar excepciones o código
de limpieza para un grupo de sentencias:

   try_stmt  ::= try1_stmt | try2_stmt
   try1_stmt ::= "try" ":" suite
                 ("except" [expression ["as" identifier]] ":" suite)+
                 ["else" ":" suite]
                 ["finally" ":" suite]
   try2_stmt ::= "try" ":" suite
                 "finally" ":" suite

The "except" clause(s) specify one or more exception handlers. When no
exception occurs in the "try" clause, no exception handler is
executed. When an exception occurs in the "try" suite, a search for an
exception handler is started.  This search inspects the except clauses
in turn until one is found that matches the exception.  An expression-
less except clause, if present, must be last; it matches any
exception.  For an except clause with an expression, that expression
is evaluated, and the clause matches the exception if the resulting
object is "compatible" with the exception.  An object is compatible
with an exception if the object is the class or a *non-virtual base
class* of the exception object, or a tuple containing an item that is
the class or a non-virtual base class of the exception object.

Si ninguna cláusula "except" coincide con la excepción, la búsqueda de
un gestor de excepciones continúa en el código circundante y en la
pila de invocación. [1]

Si la evaluación de una expresión en el encabezado de una cláusula
"except" genera una excepción, la búsqueda original de un gestor se
cancela y se inicia la búsqueda de la nueva excepción en el código
circundante y en la pila de llamadas (se trata como si toda la
sentencia "try" provocó la excepción).

Cuando se encuentra una cláusula "except" coincidente, la excepción se
asigna al destino especificado después de la palabra clave "as" en esa
cláusula "except", si está presente, y se ejecuta la suite de
cláusulas "except". Todas las cláusulas "except" deben tener un bloque
ejecutable. Cuando se alcanza el final de este bloque, la ejecución
continúa normalmente después de toda la sentencia try. (Esto significa
que si existen dos gestores de errores anidados para la misma
excepción, y la excepción ocurre en la cláusula "try" del gestor
interno, el gestor externo no gestionará la excepción).

Cuando se ha asignado una excepción usando "as target", se borra al
final de la cláusula "except". Esto es como si

   except E as N:
       foo

fue traducido a

   except E as N:
       try:
           foo
       finally:
           del N

Esto significa que la excepción debe asignarse a un nombre diferente
para poder referirse a ella después de la cláusula "except". Las
excepciones se borran porque con el seguimiento vinculado a ellas,
forman un bucle de referencia con el marco de la pila, manteniendo
activos todos los locales en esa pila hasta que ocurra la próxima
recolección de basura.

Antes de que se ejecute un conjunto de cláusulas "except", los
detalles sobre la excepción se almacenan en el módulo "sys" y se puede
acceder a través de "sys.exc_info()". "sys.exc_info()" retorna 3
tuplas que consisten en la clase de excepción, la instancia de
excepción y un objeto de rastreo (ver sección Jerarquía de tipos
estándar) que identifica el punto en el programa donde ocurrió la
excepción. Lo valores "sys.exc_info()" se restauran a sus valores
anteriores (antes de la llamada) al regresar de una función que manejó
una excepción.

La cláusula opcional "else" se ejecuta si el flujo de control sale de
la suite "try", no se produjo ninguna excepción, y no se ejecutó la
sentencia "return", "continue" o "break". Las excepciones en la
cláusula "else" no se gestionaron con las cláusulas precedentes
"except".

Si está presente "finally", esto especifica un gestor de 'limpieza'.
La cláusula "try" se ejecuta, incluidas las cláusulas "except" y
"else". Si se produce una excepción en cualquiera de las cláusulas y
no se maneja, la excepción se guarda temporalmente. Se ejecuta la
cláusula "finally". Si hay una excepción guardada, se vuelve a generar
al final de la cláusula "finally". Si la cláusula "finally" genera
otra excepción, la excepción guardada se establece como el contexto de
la nueva excepción. Si la cláusula "finally" ejecuta una sentencia
"return", "break" o "continue", la excepción guardada se descarta:

   >>> def f():
   ...     try:
   ...         1/0
   ...     finally:
   ...         return 42
   ...
   >>> f()
   42

La información de excepción no está disponible para el programa
durante la ejecución de la cláusula "finally".

Cuando se ejecuta una sentencia "return", "break" o "continue" en la
suite "try" de un "try"...la sentencia "finally", la cláusula
"finally" también se ejecuta 'al salir'.

El valor de retorno de una función está determinado por la última
sentencia "return" ejecutada. Dado que la cláusula "finally" siempre
se ejecuta, una sentencia "return" ejecutada en la cláusula "finally"
siempre será la última ejecutada:

   >>> def foo():
   ...     try:
   ...         return 'try'
   ...     finally:
   ...         return 'finally'
   ...
   >>> foo()
   'finally'

Se puede encontrar información adicional sobre las excepciones en la
sección Excepciones, e información sobre el uso de la sentencia
"raise", para generar excepciones se puede encontrar en la sección La
declaración raise.

Distinto en la versión 3.8: Antes de Python 3.8, una sentencia
"continue" era ilegal en la cláusula "finally" debido a un problema
con la implementación.


8.5. La sentencia "with"
========================

La sentencia "with" se usa para ajustar la ejecución de un bloque con
métodos definidos por un administrador de contexto (ver sección
Gestores de Contexto en la Declaración with). Esto permite que los
patrones de uso comunes "try"..."except"..."finally" se encapsulen
para una reutilización conveniente.

   with_stmt ::= "with" with_item ("," with_item)* ":" suite
   with_item ::= expression ["as" target]

La ejecución de la sentencia "with" con un "item" se realiza de la
siguiente manera:

1. La expresión de contexto (la expresión dada en "with_item") se
   evalúa para obtener un administrador de contexto.

2. El administrador de contexto "__enter__()" se carga para su uso
   posterior.

3. El administrador de contexto "__exit__()" se carga para su uso
   posterior.

4. Se invoca el método del administrador de contexto "__enter__()".

5. Si se incluyó el destino en la sentencia "with", se le asigna el
   valor de retorno de "__enter__()".

   Nota:

     La sentencia "with" garantiza que si el método "__enter__()"
     regresa sin error, entonces siempre se llamará a "__exit__()".
     Por lo tanto, si se produce un error durante la asignación a la
     lista de destino, se tratará de la misma manera que si se
     produciría un error dentro de la suite. Vea el paso 6 a
     continuación.

6. La suite se ejecuta.

7. Se invoca el método del administrador de contexto "__exit__()". Si
   una excepción causó la salida de la suite, su tipo, valor y rastreo
   se pasan como argumentos a "__exit__()". De lo contrario, se
   proporcionan tres argumentos "None".

   Si se salió de la suite debido a una excepción, y el valor de
   retorno del método "__exit__()" fue falso, la excepción se vuelve a
   plantear. Si el valor de retorno era verdadero, la excepción se
   suprime y la ejecución continúa con la sentencia que sigue a la
   sentencia "with".

   Si se salió de la suite por cualquier motivo que no sea una
   excepción, el valor de retorno de "__exit__()" se ignora y la
   ejecución continúa en la ubicación normal para el tipo de salida
   que se tomó.

El siguiente código:

   with EXPRESSION as TARGET:
       SUITE

es semánticamente equivalente a:

   manager = (EXPRESSION)
   enter = type(manager).__enter__
   exit = type(manager).__exit__
   value = enter(manager)
   hit_except = False

   try:
       TARGET = value
       SUITE
   except:
       hit_except = True
       if not exit(manager, *sys.exc_info()):
           raise
   finally:
       if not hit_except:
           exit(manager, None, None, None)

Con más de un elemento, los administradores de contexto se procesan
como si varias sentencias "with" estuvieran anidadas:

   with A() as a, B() as b:
       SUITE

es semánticamente equivalente a:

   with A() as a:
       with B() as b:
           SUITE

Distinto en la versión 3.1: Soporte para múltiples expresiones de
contexto.

Ver también:

  **PEP 343** - La sentencia "with"
     La especificación, antecedentes y ejemplos de la sentencia de
     Python "with".


8.6. Definiciones de funciones
==============================

Una definición de función define una función objeto determinada por el
usuario (consulte la sección Jerarquía de tipos estándar):

   funcdef                   ::= [decorators] "def" funcname "(" [parameter_list] ")"
               ["->" expression] ":" suite
   decorators                ::= decorator+
   decorator                 ::= "@" assignment_expression NEWLINE
   parameter_list            ::= defparameter ("," defparameter)* "," "/" ["," [parameter_list_no_posonly]]
                        | parameter_list_no_posonly
   parameter_list_no_posonly ::= defparameter ("," defparameter)* ["," [parameter_list_starargs]]
                                 | parameter_list_starargs
   parameter_list_starargs   ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
                               | "**" parameter [","]
   parameter                 ::= identifier [":" expression]
   defparameter              ::= parameter ["=" expression]
   funcname                  ::= identifier

Una definición de función es una sentencia ejecutable. Su ejecución
vincula el nombre de la función en el espacio de nombres local actual
a un objeto de función (un contenedor alrededor del código ejecutable
para la función). Este objeto de función contiene una referencia al
espacio de nombres global actual como el espacio de nombres global que
se utilizará cuando se llama a la función.

La definición de la función no ejecuta el cuerpo de la función; esto
se ejecuta solo cuando se llama a la función. [2]

Una definición de función puede estar envuelta por una o más
expresiones *decorator*. Las expresiones de decorador se evalúan
cuando se define la función, en el ámbito que contiene la definición
de la función. El resultado debe ser invocable, la cual se invoca con
el objeto de función como único argumento. El valor retornado está
vinculado al nombre de la función en lugar del objeto de la función.
Se aplican múltiples decoradores de forma anidada. Por ejemplo, el
siguiente código

   @f1(arg)
   @f2
   def func(): pass

es más o menos equivalente a

   def func(): pass
   func = f1(arg)(f2(func))

excepto que la función original no está vinculada temporalmente al
nombre "func".

Distinto en la versión 3.9: Las funciones se pueden decorar con
cualquier token válido "assignment_expression". Anteriormente, la
gramática era mucho más restrictiva; ver **PEP 614** para más
detalles.

Cuando uno o más *parameters* tienen la forma *parameter* "="
*expression*, se dice que la función tiene "valores de parámetros
predeterminados". Para un parámetro con un valor predeterminado, el
correspondiente *argument* puede omitirse desde una llamada, en cuyo
caso se sustituye el valor predeterminado del parámetro. Si un
parámetro tiene un valor predeterminado, todos los parámetros
siguientes hasta el ""*"" también deben tener un valor predeterminado
--- esta es una restricción sintáctica que la gramática no expresa.

**Los valores de los parámetros predeterminados se evalúan de
izquierda a derecha cuando se ejecuta la definición de la función.**
Esto significa que la expresión se evalúa una vez, cuando se define la
función, y que se utiliza el mismo valor "precalculado" para cada
llamada . Esto es especialmente importante para entender cuando un
parámetro predeterminado es un objeto mutable, como una lista o un
diccionario: si la función modifica el objeto (por ejemplo, al agregar
un elemento a una lista), el valor predeterminado está en efecto
modificado. Esto generalmente no es lo que se pretendía. Una forma de
evitar esto es usar "None" como valor predeterminado y probarlo
explícitamente en el cuerpo de la función, por ejemplo:

   def whats_on_the_telly(penguin=None):
       if penguin is None:
           penguin = []
       penguin.append("property of the zoo")
       return penguin

Function call semantics are described in more detail in section
Invocaciones. A function call always assigns values to all parameters
mentioned in the parameter list, either from positional arguments,
from keyword arguments, or from default values.  If the form
""*identifier"" is present, it is initialized to a tuple receiving any
excess positional parameters, defaulting to the empty tuple. If the
form ""**identifier"" is present, it is initialized to a new ordered
mapping receiving any excess keyword arguments, defaulting to a new
empty mapping of the same type.  Parameters after ""*"" or
""*identifier"" are keyword-only parameters and may only be passed by
keyword arguments.  Parameters before ""/"" are positional-only
parameters and may only be passed by positional arguments.

Distinto en la versión 3.8: The "/" function parameter syntax may be
used to indicate positional-only parameters. See **PEP 570** for
details.

Los parámetros pueden tener *annotation* de la forma "": expression""
que sigue al nombre del parámetro. Cualquier parámetro puede tener una
anotación, incluso las de la forma "*identifier" o "** identifier".
Las funciones pueden tener una anotación "return" de la forma ""->
expression"" después de la lista de parámetros. Estas anotaciones
pueden ser cualquier expresión válida de Python. La presencia de
anotaciones no cambia la semántica de una función. Los valores de
anotación están disponibles como valores de un diccionario con los
nombres de los parámetros en el atributo "__annotations__" del objeto
de la función. Si se usa "annotations" importada desde "__future__",
las anotaciones se conservan como cadenas de caracteres en tiempo de
ejecución que permiten la evaluación pospuesta. De lo contrario, se
evalúan cuando se ejecuta la definición de la función. En este caso,
las anotaciones pueden evaluarse en un orden diferente al que aparecen
en el código fuente.

También es posible crear funciones anónimas (funciones no vinculadas a
un nombre), para uso inmediato en expresiones. Utiliza expresiones
lambda, descritas en la sección Lambdas. Tenga en cuenta que la
expresión lambda es simplemente una abreviatura para una definición de
función simplificada; una función definida en una sentencia ""def""
puede pasarse o asignarse a otro nombre al igual que una función
definida por una expresión lambda. La forma ""def"" es en realidad más
poderosa ya que permite la ejecución de múltiples sentencias y
anotaciones.

**Nota del programador:** Las funciones son objetos de la primera-
clase. Una sentencia ""def"" ejecutada dentro de una definición de
función define una función local que se puede retornar o pasar. Las
variables libres utilizadas en la función anidada pueden acceder a las
variables locales de la función que contiene el def. Vea la sección
Nombres y vínculos para más detalles.

Ver también:

  **PEP 3107** - Anotaciones de funciones
     La especificación original para anotaciones de funciones.

  **PEP 484** - Sugerencias de tipo
     Definición de un significado estándar para anotaciones:
     sugerencias de tipo.

  **PEP 526** - Sintaxis para anotaciones variables
     Capacidad para escribir declaraciones de variables indirectas,
     incluidas variables de clase y variables de instancia

  **PEP 563** - Evaluación pospuesta de anotaciones
     Admite referencias directas dentro de las anotaciones conservando
     las anotaciones en forma de cadena de caracteres en tiempo de
     ejecución en lugar de una evaluación apresurada.


8.7. Definiciones de clase
==========================

Una definición de clase define un objeto de clase (ver sección
Jerarquía de tipos estándar):

   classdef    ::= [decorators] "class" classname [inheritance] ":" suite
   inheritance ::= "(" [argument_list] ")"
   classname   ::= identifier

Una definición de clase es una sentencia ejecutable. La lista de
herencia generalmente proporciona una lista de clases base (consulte
Metaclases para usos más avanzados), por lo que cada elemento de la
lista debe evaluar a un objeto de clase que permita la
subclasificación. Las clases sin una lista de herencia heredan, por
defecto, de la clase base "object"; por lo tanto,

   class Foo:
       pass

es equivalente a

   class Foo(object):
       pass

La suite de la clase se ejecuta en un nuevo marco de ejecución (ver
Nombres y vínculos), usando un espacio de nombres local recién creado
y el espacio de nombres global original. (Por lo general, el bloque
contiene principalmente definiciones de funciones). Cuando la suite de
la clase finaliza la ejecución, su marco de ejecución se descarta pero
se guarda su espacio de nombres local. [3] Luego se crea un objeto de
clase utilizando la lista de herencia para las clases base y el
espacio de nombres local guardado para el diccionario de atributos. El
nombre de la clase está vinculado a este objeto de clase en el espacio
de nombres local original.

El orden en que se definen los atributos en el cuerpo de la clase se
conserva en el "__dict__" de la nueva clase. Tenga en cuenta que esto
es confiable solo justo después de crear la clase y solo para las
clases que se definieron utilizando la sintaxis de definición.

La creación de clases se puede personalizar en gran medida usando
metaclasses.

Las clases también se pueden decorar: al igual que cuando se decoran
funciones,

   @f1(arg)
   @f2
   class Foo: pass

es más o menos equivalente a

   class Foo: pass
   Foo = f1(arg)(f2(Foo))

Las reglas de evaluación para las expresiones de decorador son las
mismas que para los decoradores de funciones. El resultado se vincula
al nombre de la clase.

Distinto en la versión 3.9: Las clases se pueden decorar con cualquier
token válido "assignment_expression". Anteriormente, la gramática era
mucho más restrictiva; ver **PEP 614** para más detalles.

** Nota del programador: ** Las variables definidas en la definición
de la clase son atributos de clase; son compartidos por instancias.
Los atributos de instancia se pueden establecer en un método con
"self.name = value". Se puede acceder a los atributos de clase e
instancia a través de la notación ""self.name"", y un atributo de
instancia oculta un atributo de clase con el mismo nombre cuando se
accede de esta manera. Los atributos de clase se pueden usar como
valores predeterminados para los atributos de instancia, pero el uso
de valores mutables puede generar resultados inesperados. Descriptors
se puede usar para crear variables de instancia con diferentes
detalles de implementación.

Ver también:

  **PEP 3115** - Metaclases en Python 3000
     La propuesta que cambió la declaración de metaclases a la
     sintaxis actual y la semántica de cómo se construyen las clases
     con metaclases.

  **PEP 3129** - Decoradores de clase
     La propuesta que agregó decoradores de clase. Los decoradores de
     funciones y métodos se introdujeron en **PEP 318**.


8.8. Corrutinas
===============

Nuevo en la versión 3.5.


8.8.1. Definición de la función corrutina
-----------------------------------------

   async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")"
                     ["->" expression] ":" suite

La ejecución de las corrutinas de Python puede suspenderse y
reanudarse en muchos puntos (ver *coroutine*). Dentro del cuerpo de
una función de corrutina, los identificadores "await" y "async" se
convierten en palabras claves reservadas; las expresiones "await",
"async for" y "async with" solo se puede usar en los cuerpos de
funciones de corrutina.

Las funciones definidas con la sintaxis "async def" siempre son
funciones de corrutina, incluso si no contienen palabras claves
"await" o "async".

Es un error del tipo "SyntaxError" usar una expresión "yield from"
dentro del cuerpo de una función de corrutina.

Un ejemplo de una función corrutina:

   async def func(param1, param2):
       do_stuff()
       await some_coroutine()


8.8.2. La sentencia "async for"
-------------------------------

   async_for_stmt ::= "async" for_stmt

Un *asynchronous iterable* proporciona un método "__aiter__" que
retorna directamente un *asynchronous iterator*, que puede llamar a
código asincrónico en su método "__anext__".

La sentencia "async for" permite una iteración apropiada sobre
iteradores asincrónicos.

El siguiente código:

   async for TARGET in ITER:
       SUITE
   else:
       SUITE2

Es semánticamente equivalente a:

   iter = (ITER)
   iter = type(iter).__aiter__(iter)
   running = True

   while running:
       try:
           TARGET = await type(iter).__anext__(iter)
       except StopAsyncIteration:
           running = False
       else:
           SUITE
   else:
       SUITE2

Ver también "__aiter__()" y "__anext__()" para más detalles.

Es un error del tipo "SyntaxError" usar una sentencia "async for"
fuera del cuerpo de una función de corrutina.


8.8.3. La sentencia "async with"
--------------------------------

   async_with_stmt ::= "async" with_stmt

Un *asynchronous context manager* es un *context manager* que puede
suspender la ejecución en sus métodos *enter* y *exit*.

El siguiente código:

   async with EXPRESSION as TARGET:
       SUITE

es semánticamente equivalente a:

   manager = (EXPRESSION)
   aenter = type(manager).__aenter__
   aexit = type(manager).__aexit__
   value = await aenter(manager)
   hit_except = False

   try:
       TARGET = value
       SUITE
   except:
       hit_except = True
       if not await aexit(manager, *sys.exc_info()):
           raise
   finally:
       if not hit_except:
           await aexit(manager, None, None, None)

Ver también "__aenter__()" y "__aexit__()" para más detalles.

Es un error del tipo "SyntaxError" usar una sentencia "async with"
fuera del cuerpo de una función de corrutina.

Ver también:

  **PEP 492** - Corrutinas con sintaxis "async" y "await"
     La propuesta que convirtió a las corrutinas en un concepto
     independiente adecuado en Python, y agregó una sintaxis de
     soporte.

-[ Notas al pie ]-

[1] La excepción se propaga a la pila de invocación a menos que haya
    una cláusula "finally" que provoque otra excepción. Esa nueva
    excepción hace que se pierda la anterior.

[2] Una cadena de caracteres literal que aparece como la primera
    sentencia en el cuerpo de la función se transforma en el atributo
    "__doc__" de la función y, por lo tanto, en funciones *docstring*.

[3] Una cadena de caracteres literal que aparece como la primera
    sentencia en el cuerpo de la clase se transforma en el elemento
    del espacio de nombre "__doc__" y, por lo tanto, de la clase
    *docstring*.
