# 7. Les instructions simples

Une instruction simple est contenue dans une seule ligne logique. Plusieurs instructions simples peuvent être écrites sur une seule ligne, séparées par des points-virgules. La syntaxe d'une instruction simple est :

    simple_stmt: expression_stmt
                 | assert_stmt
                 | assignment_stmt
                 | augmented_assignment_stmt
                 | annotated_assignment_stmt
                 | pass_stmt
                 | del_stmt
                 | return_stmt
                 | yield_stmt
                 | raise_stmt
                 | break_stmt
                 | continue_stmt
                 | import_stmt
                 | future_stmt
                 | global_stmt
                 | nonlocal_stmt
                 | type_stmt

## 7.1. Les expressions

Les expressions sont utilisées (généralement de manière interactive) comme instructions pour calculer et écrire des valeurs, appeler une procédure (une fonction dont le résultat renvoyé n'a pas d'importance ; en Python, les procédures renvoient la valeur `None`). D'autres utilisations des expressions sont autorisées et parfois utiles. La syntaxe pour une expression en tant qu'instruction est :

    expression_stmt: starred_expression

Ce genre d'instruction évalue la liste d'expressions (qui peut se limiter à une seule expression).

En mode interactif, si la valeur n'est pas `None`, elle est convertie en chaîne en utilisant la fonction native `repr()` et la chaîne résultante est écrite sur la sortie standard sur sa propre ligne. Si le résultat est `None`, rien n'est écrit ce qui est usuel pour les appels de procédures.

## 7.2. Les assignations

Les assignations sont utilisées pour lier ou relier des noms à des valeurs et modifier des attributs ou des éléments d'objets mutables :

    assignment_stmt: (target_list "=")+ (starred_expression | yield_expression)
    target_list:     target ("," target)* [","]
    target:          identifier
                     | "(" [target_list] ")"
                     | "[" [target_list] "]"
                     | attributeref
                     | subscription
                     | "*" target

(See section Primaires for the syntax definitions for attributeref and subscription.)

Une assignation évalue la liste d'expressions (gardez en mémoire que ce peut être une simple expression ou une liste dont les éléments sont séparés par des virgules, cette dernière produisant un n-uplet) et assigne l'unique objet résultant à chaque liste cible, de la gauche vers la droite.

Assignment is defined recursively depending on the form of the target (list). When a target is part of a mutable object (an attribute reference or subscription), the mutable object must ultimately perform the assignment and decide about its validity, and may raise an exception if the assignment is unacceptable. The rules observed by various types and the exceptions raised are given with the definition of the object types (see section Hiérarchie des types standards).

L'assignation d'un objet à une liste cible, optionnellement entourée par des parenthèses ou des crochets, est définie récursivement comme suit.

- Si la liste cible est une cible unique sans virgule de fin, optionnellement entre parenthèses, l'objet est assigné à cette cible.

- Sinon :

  - Si la liste cible contient une cible préfixée par un astérisque, appelée cible étoilée (starred target en anglais) : l'objet doit être un itérable avec au moins autant d'éléments qu'il y a de cibles dans la liste cible, moins un. Les premiers éléments de l'itérable sont assignés, de la gauche vers la droite, aux cibles avant la cible étoilée. Les éléments de queue de l'itérable sont assignés aux cibles après la cible étoilée. Une liste des éléments restants dans l'itérable est alors assignée à la cible étoilée (cette liste peut être vide).

  - Sinon : l'objet doit être un itérable avec le même nombre d'éléments qu'il y a de cibles dans la liste cible ; les éléments sont assignés, de la gauche vers la droite, vers les cibles correspondantes.

L'assignation d'un objet vers une cible unique est définie récursivement comme suit.

- Si la cible est une variable (un nom) :

  - si le nom n'apparaît pas dans une instruction `global` ou `nonlocal` (respectivement) du bloc de code courant, le nom est lié à l'objet dans l'espace courant des noms locaux ;

  - sinon le nom est lié à l'objet dans l'espace des noms globaux ou dans un espace de nommage plus large déterminé par `nonlocal`, respectivement.

  Le lien du nom est modifié si le nom était déjà lié. Ceci peut faire que le compteur de références de l'objet auquel le nom était précédemment lié tombe à zéro, entrainant la dé-allocation de l'objet et l'appel de son destructeur (s'il existe).

- Si la cible est une référence à un attribut : l'expression primaire de la référence est évaluée. Elle doit produire un objet avec des attributs que l'on peut assigner : si ce n'est pas le cas, une `TypeError` est levée. Python demande alors à cet objet d'assigner l'attribut donné ; si ce n'est pas possible, une exception est levée (habituellement, mais pas nécessairement, `AttributeError`).

  Note : si l'objet est une instance de classe et que la référence à l'attribut apparaît des deux côtés de l'opérateur d'assignation, l'expression « à droite », `a.x` peut accéder soit à l'attribut d'instance ou (si cet attribut d'instance n'existe pas) à l'attribut de classe. L'expression cible « à gauche » `a.x` est toujours définie comme un attribut d'instance, en le créant si nécessaire. Ainsi, les deux occurrences de `a.x` ne font pas nécessairement référence au même attribut : si l'expression « à droite » fait référence à un attribut de classe, l'expression « à gauche » crée un nouvel attribut d'instance comme cible de l'assignation :

      class Cls:
          x = 3             # class variable
      inst = Cls()
      inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3

  Cette description ne s'applique pas nécessairement aux attributs des descripteurs, telles que les propriétés créées avec `property()`.

- If the target is a subscription: The primary expression in the reference is evaluated. Next, the subscript expression is evaluated. Then, the primary's `__setitem__()` method is called with two arguments: the subscript and the assigned object.

  Typically, `__setitem__()` is defined on mutable sequence objects (such as lists) and mapping objects (such as dictionaries), and behaves as follows.

  Si la primaire est un objet séquence mutable (telle qu'une liste), la sélection doit produire un entier. S'il est négatif, la longueur de la séquence lui est ajoutée. La valeur résultante doit être un entier positif ou nul, plus petit que la longueur de la séquence, et Python demande à la séquence d'assigner l'objet à l'élément se trouvant à cet indice. Si l'indice est hors limites, une `IndexError` est levée (une assignation à une sélection dans une séquence ne peut pas ajouter de nouveaux éléments à une liste).

  Si la primaire est un objet tableau de correspondances (tel qu'un dictionnaire), la sélection doit être d'un type compatible avec le type des clés ; Python demande alors au tableau de correspondances de créer un couple clé-valeur qui associe la sélection à l'objet assigné. Ceci peut remplacer une correspondance déjà existante pour une clé donnée ou insérer un nouveau couple clé-valeur.

  If the target is a slicing: The primary expression should evaluate to a mutable sequence object (such as a list). The assigned object should be iterable. The slicing's lower and upper bounds should be integers; if they are `None` (or not present), the defaults are zero and the sequence's length. If either bound is negative, the sequence's length is added to it. The resulting bounds are clipped to lie between zero and the sequence's length, inclusive. Finally, the sequence object is asked to replace the slice with the items of the assigned sequence. The length of the slice may be different from the length of the assigned sequence, thus changing the length of the target sequence, if the target sequence allows it.

Bien que la définition de l'assignation implique que le passage entre le côté gauche et le côté droit soient « simultanés » (par exemple, `a, b = b, a` permute les deux variables), le passage à l'intérieur des collections de variables que l'on assigne intervient de la gauche vers la droite, ce qui peut entraîner quelques confusions. Par exemple, le programme suivant affiche `[0, 2]` :

    x = [0, 1]
    i = 0
    i, x[i] = 1, 2         # i is updated, then x[i] is updated
    print(x)

Voir aussi

PEP 3132 -- dépaquetage étendu d'itérable

  Spécification de la fonctionnalité `*cible`.

### 7.2.1. Les assignations augmentées

Une assignation augmentée est la combinaison, dans une seule instruction, d'une opération binaire et d'une assignation :

    augmented_assignment_stmt: augtarget augop (expression_list | yield_expression)
    augtarget:                 identifier | attributeref | subscription
    augop:                     "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="

Voir la section Primaires pour la définition des syntaxes des trois derniers symboles.

Une assignation augmentée évalue la cible (qui, au contraire des assignations normales, ne peut pas être un dépaquetage) et la liste d'expressions, effectue l'opération binaire (spécifique au type d'assignation) sur les deux opérandes et assigne le résultat à la cible originale. La cible n'est évaluée qu'une seule fois.

An augmented assignment statement like `x += 1` can be rewritten as `x = x + 1` to achieve a similar, but not exactly equal effect. In the augmented version, `x` is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.

Au contraire des assignations normales, les assignations augmentées évaluent la partie gauche avant d'évaluer la partie droite. Par exemple, `a[i] += f(x)` commence par s'intéresser à `a[i]`, puis Python évalue `f(x)`, effectue l'addition et, enfin, écrit le résultat dans `a[i]`.

À l'exception de l'assignation de n-uplets et de cibles multiples dans une seule instruction, l'assignation effectuée par une assignation augmentée est traitée de la même manière qu'une assignation normale. De même, à l'exception du comportement possible sur place, l'opération binaire effectuée par assignation augmentée est la même que les opérations binaires normales.

Pour les cibles qui sont des références à des attributs, la même mise en garde sur les attributs de classe et d'instances s'applique que pour les assignations normales.

### 7.2.2. Les assignations annotées

Une assignation annotée est la combinaison, dans une seule instruction, d'une annotation de variable ou d'attribut et d'une assignation optionnelle :

    annotated_assignment_stmt: augtarget ":" expression
                               ["=" (starred_expression | yield_expression)]

La différence avec une assignation normale (voir ci-dessus) est qu'une seule cible est autorisée.

The assignment target is considered "simple" if it consists of a single name that is not enclosed in parentheses. For simple assignment targets, if in class or module scope, the annotations are gathered in a lazily evaluated annotation scope. The annotations can be evaluated using the `__annotations__` attribute of a class or module, or using the facilities in the `annotationlib` module.

If the assignment target is not simple (an attribute, subscript node, or parenthesized name), the annotation is never evaluated.

Si le nom est annoté dans la portée d'une fonction, alors ce nom est local à cette portée. Les annotations ne sont jamais évaluées et stockées dans les portées des fonctions.

If the right hand side is present, an annotated assignment performs the actual assignment as if there was no annotation present. If the right hand side is not present for an expression target, then the interpreter evaluates the target except for the last `__setitem__()` or `__setattr__()` call.

Voir aussi

PEP 526 -- Syntaxe pour les annotations de variables

  La proposition qui a ajouté la syntaxe pour annoter les types de variables (y compris les variables de classe et les variables d'instance), au lieu de les exprimer par le biais de commentaires.

PEP 484 -- Indices de type

  La proposition qui a ajouté le module `typing` pour fournir une syntaxe standard pour les annotations de type qui peuvent être utilisées dans les outils d'analyse statique et les environnements de développement intégrés (EDI).

Modifié dans la version 3.8: Dorénavant, côté droit des assignations annotées, peuvent figurer les mêmes expressions que pour les assignations normales. Auparavant, certaines expressions (comme des n-uplets sans parenthèse englobante) généraient des erreurs de syntaxe.

Modifié dans la version 3.14: Annotations are now lazily evaluated in a separate annotation scope. If the assignment target is not simple, annotations are never evaluated.

## 7.3. L'instruction `assert`

Les instructions `assert` sont une manière pratique d'insérer des tests de débogage au sein d'un programme :

    assert_stmt: "assert" expression ["," expression]

La forme la plus simple, `assert expression`, est équivalente à :

    if __debug__:
        if not expression: raise AssertionError

La forme étendue, `assert expression1, expression2`, est équivalente à :

    if __debug__:
        if not expression1: raise AssertionError(expression2)

These equivalences assume that `__debug__` and `AssertionError` refer to the built-in variables with those names. In the current implementation, the built-in variable `__debug__` is `True` under normal circumstances, `False` when optimization is requested (command line option `-O`). The current code generator emits no code for an `assert` statement when optimization is requested at compile time. Note that it is unnecessary to include the source code for the expression that failed in the error message; it will be displayed as part of the stack trace.

Assigner vers `__debug__` est illégal. La valeur de cette variable native est déterminée au moment où l'interpréteur démarre.

## 7.4. L'instruction `pass`

    pass_stmt: "pass"

`pass` est une opération vide. Quand elle est exécutée, rien ne se passe. Elle est utile comme bouche-trou lorsqu'une instruction est syntaxiquement requise mais qu'aucun code ne doit être exécuté. Par exemple :

    def f(arg): pass    # a function that does nothing (yet)

    class C: pass       # a class with no methods (yet)

## 7.5. L'instruction `del`

    del_stmt: "del" target_list

La suppression est récursivement définie de la même manière que l'assignation. Plutôt que de détailler cela de manière approfondie, voici quelques indices.

La suppression d'une liste cible (target_list dans la grammaire ci-dessus) supprime récursivement chaque cible, de la gauche vers la droite.

Deletion of a name removes the binding of that name from the local or global namespace, depending on whether the name occurs in a `global` statement in the same code block. Trying to delete an unbound name raises a `NameError` exception.

Deletion of attribute references and subscriptions is passed to the primary object involved; deletion of a slicing is in general equivalent to assignment of an empty slice of the right type (but even this is determined by the sliced object).

Modifié dans la version 3.2: Auparavant, il était illégal de supprimer un nom dans l'espace des noms locaux si celui-ci apparaissait comme variable libre dans un bloc imbriqué.

## 7.6. L'instruction `return`

    return_stmt: "return" [expression_list]

`return` ne peut être placée qu'à l'intérieur d'une définition de fonction, pas à l'intérieur d'une définition de classe.

Si une liste d'expressions (expression_list dans la grammaire ci-dessus) est présente, elle est évaluée, sinon `None` est utilisée comme valeur par défaut.

`return` quitte l'appel à la fonction courante avec la liste d'expressions (ou `None`) comme valeur de retour.

Quand `return` fait sortir d'une instruction `try` avec une clause `finally`, cette clause `finally` est exécutée avant de réellement quitter la fonction.

Dans une fonction génératrice, l'instruction `return` indique que le générateur est terminé et provoque la levée d'une `StopIteration`. La valeur de retour (s'il y en a une) est utilisée comme argument pour construire l'exception `StopIteration` et devient l'attribut `StopIteration.value`.

Dans une fonction génératrice asynchrone, une instruction `return` vide indique que le générateur asynchrone est terminé et provoque la levée d'une `StopAsyncIteration`. Une instruction `return` non vide est une erreur de syntaxe dans une fonction génératrice asynchrone.

## 7.7. L'instruction `yield`

    yield_stmt: yield_expression

A `yield` statement is semantically equivalent to a yield expression. The `yield` statement can be used to omit the parentheses that would otherwise be required in the equivalent yield expression statement. For example, the yield statements

    yield <expr>
    yield from <expr>

sont équivalentes aux instructions expressions yield :

    (yield <expr>)
    (yield from <expr>)

Yield expressions and statements are only used when defining a generator function, and are only used in the body of the generator function. Using `yield` in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.

Pour tous les détails sur la sémantique de `yield`, reportez-vous à la section Expressions yield.

## 7.8. L'instruction `raise`

    raise_stmt: "raise" [expression ["from" expression]]

Si aucune expression n'est présente, `raise` propage l'exception en cours de traitement, aussi dénommée exception active. Si aucune exception n'est active, une exception `RuntimeError` est levée, indiquant que c'est une erreur.

Sinon, `raise` évalue la première expression en tant qu'objet exception. Ce doit être une sous-classe ou une instance de `BaseException`. Si c'est une classe, l'instance de l'exception est obtenue en instanciant la classe sans argument (au moment voulu).

Le type de l'exception est la classe de l'instance de l'exception, la value est l'instance elle-même.

A traceback object is normally created automatically when an exception is raised and attached to it as the `__traceback__` attribute. You can create an exception and set your own traceback in one step using the `with_traceback()` exception method (which returns the same exception instance, with its traceback set to its argument), like so:

    raise Exception("foo occurred").with_traceback(tracebackobj)

The `from` clause is used for exception chaining: if given, the second expression must be another exception class or instance. If the second expression is an exception instance, it will be attached to the raised exception as the `__cause__` attribute (which is writable). If the expression is an exception class, the class will be instantiated and the resulting exception instance will be attached to the raised exception as the `__cause__` attribute. If the raised exception is not handled, both exceptions will be printed:

    >>> try:
    ...     print(1 / 0)
    ... except Exception as exc:
    ...     raise RuntimeError("Something bad happened") from exc
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
        print(1 / 0)
              ~~^~~
    ZeroDivisionError: division by zero

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
        raise RuntimeError("Something bad happened") from exc
    RuntimeError: Something bad happened

A similar mechanism works implicitly if a new exception is raised when an exception is already being handled. An exception may be handled when an `except` or `finally` clause, or a `with` statement, is used. The previous exception is then attached as the new exception's `__context__` attribute:

    >>> try:
    ...     print(1 / 0)
    ... except:
    ...     raise RuntimeError("Something bad happened")
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
        print(1 / 0)
              ~~^~~
    ZeroDivisionError: division by zero

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
        raise RuntimeError("Something bad happened")
    RuntimeError: Something bad happened

Exception chaining can be explicitly suppressed by specifying `None` in the `from` clause:

    >>> try:
    ...     print(1 / 0)
    ... except:
    ...     raise RuntimeError("Something bad happened") from None
    ...
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
    RuntimeError: Something bad happened

Des informations complémentaires sur les exceptions sont disponibles dans la section Exceptions et sur la gestion des exceptions dans la section L'instruction try.

Modifié dans la version 3.3: `None` est dorénavant autorisée en tant que `Y` dans `raise X from Y`.

Added the `__suppress_context__` attribute to suppress automatic display of the exception context.

Modifié dans la version 3.11: si la trace d'appels de l'exception active est modifiée dans une clause `except`, une instruction `raise` postérieure lève à nouveau l'exception avec la trace modifiée. Auparavant, l'exception était levée à nouveau avec la trace qu'elle avait au moment de son interception.

## 7.9. L'instruction `break`

    break_stmt: "break"

Une instruction `break` ne peut apparaître qu'à l'intérieur d'une boucle `for` ou `while`, mais pas dans une définition de fonction ou de classe à l'intérieur de cette boucle.

Elle termine la boucle la plus imbriquée, shuntant l'éventuelle clause `else` de la boucle.

Si une boucle `for` est terminée par un `break`, la cible qui contrôle la boucle garde sa valeur.

Quand `break` passe le contrôle en dehors d'une instruction `try` qui comporte une clause `finally`, cette clause `finally` est exécutée avant de quitter la boucle.

## 7.10. L'instruction `continue`

    continue_stmt: "continue"

L'instruction `continue` ne peut apparaître qu'à l'intérieur d'une boucle `for` ou `while`, mais pas dans une définition de fonction ou de classe à l'intérieur de cette boucle. Elle fait continuer le flot d'exécution au prochain cycle de la boucle la plus imbriquée.

Quand `continue` passe le contrôle en dehors d'une instruction `try` qui comporte une clause `finally`, cette clause `finally` est exécutée avant de commencer le cycle suivant de la boucle.

## 7.11. L'instruction `import`

    import_stmt:     ["lazy"] "import" module ["as" identifier] ("," module ["as" identifier])*
                     | ["lazy"] "from" relative_module "import" identifier ["as" identifier]
                     ("," identifier ["as" identifier])*
                     | ["lazy"] "from" relative_module "import" "(" identifier ["as" identifier]
                     ("," identifier ["as" identifier])* [","] ")"
                     | "from" relative_module "import" "*"
    module:          (identifier ".")* identifier
    relative_module: "."* module | "."+

L'instruction de base import (sans clause `from`) est exécutée en deux étapes :

1. trouve un module, le charge et l'initialise si nécessaire

2. define a name or names in the current namespace for the scope where the `import` statement occurs, just as an assignment statement would (including `global` and `nonlocal` semantics).

Quand l'instruction contient plusieurs clauses (séparées par des virgules), les deux étapes sont menées séparément pour chaque clause, comme si les clauses étaient séparées dans des instructions d'importations individuelles.

Les détails de la première étape, de recherche et de chargement des modules, sont décrits largement dans la section relative au système d'importation, qui décrit également les différents types de paquets et modules qui peuvent être importés, de même que les points d'entrée pouvant être utilisés pour personnaliser le système d'importation. Notez que des erreurs dans cette étape peuvent indiquer soit que le module n'a pas été trouvé, soit qu'une erreur s'est produite lors de l'initialisation du module, ce qui comprend l'exécution du code du module.

Si le module requis est bien récupéré, il est mis à disposition de l'espace de nommage local suivant l'une des trois façons suivantes :

- Si le nom du module est suivi par `as`, alors le nom suivant `as` est directement lié au module importé.

- si aucun autre nom n'est spécifié et que le module en cours d'importation est un module de niveau le plus haut, le nom du module est lié dans l'espace des noms locaux au module importé ;

- si le module en cours d'importation n'est pas un module de plus haut niveau, alors le nom du paquet de plus haut niveau qui contient ce module est lié dans l'espace des noms locaux au paquet de plus haut niveau. Vous pouvez accéder au module importé en utilisant son nom pleinement qualifié et non directement.

La forme `from` utilise un processus un peu plus complexe :

1. trouve le module spécifié dans la clause `from`, le charge et l'initialise si nécessaire ;

2. pour chaque nom spécifié dans les clauses `import` :

   1. vérifie si le module importé possède un attribut avec ce nom ;

   2. si non, essaie d'importer un sous-module avec ce nom puis vérifie si le module importé possède lui-même cet attribut ;

   3. si l'attribut n'est pas trouvé, une `ImportError` est levée.

   4. otherwise, a reference to that value is stored in the current namespace, using the name in the `as` clause if it is present, otherwise using the attribute name

Exemples :

    import foo                 # foo imported and bound locally
    import foo.bar.baz         # foo, foo.bar, and foo.bar.baz imported, foo bound locally
    import foo.bar.baz as fbb  # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as fbb
    from foo.bar import baz    # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as baz
    from foo import attr       # foo imported and foo.attr bound as attr

Si la liste des noms est remplacée par une étoile (`'*'`), tous les noms publics définis dans le module sont liés dans l'espace des noms locaux de la portée où apparaît l'instruction `import`.

The public names defined by a module are determined by checking the module's namespace for a variable named `__all__`; if defined, it must be a sequence of strings which are names defined or imported by that module. Names containing non-ASCII characters must be in the normalization form NFKC; see Non-ASCII characters in names for details. The names given in `__all__` are all considered public and are required to exist. If `__all__` is not defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character (`'_'`). `__all__` should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).

La forme d'import avec astérisque, `from module import *`, est autorisée seulement au niveau du module. Si vous essayez de l'utiliser dans une définition de classe ou de fonction, cela lève une `SyntaxError`.

Quand vous spécifiez les modules à importer, vous n'avez pas besoin de spécifier les noms absolus des modules. Quand un module ou un paquet est contenu dans un autre paquet, il est possible d'effectuer une importation relative à l'intérieur du même paquet de plus haut niveau sans avoir à mentionner le nom du paquet. En utilisant des points en entête du module ou du paquet spécifié après `from`, vous pouvez spécifier combien de niveaux vous souhaitez remonter dans la hiérarchie du paquet courant sans spécifier de nom exact. Un seul point en tête signifie le paquet courant où se situe le module qui effectue l'importation. Deux points signifient de remonter d'un niveau. Trois points, remonter de deux niveaux et ainsi de suite. Ainsi, si vous exécutez `from . import mod` dans un module du paquet `pkg`, vous importez finalement `pkg.mod`. Et si vous exécutez `from ..souspkg2 import mod` depuis `pkg.souspkg1`, vous importez finalement `pkg.souspkg2.mod`. La spécification des importations relatives se situe dans la section Importations relatives au paquet.

`importlib.import_module()` est fournie pour gérer les applications qui déterminent dynamiquement les modules à charger.

Lève un évènement d'audit avec les arguments `module`, `filename`, `sys.path`, `sys.meta_path`, `sys.path_hooks`.

### 7.11.1. Lazy imports

The `lazy` keyword is a soft keyword that only has special meaning when it appears immediately before an `import` or `from` statement. When an import statement is preceded by the `lazy` keyword, the import becomes lazy: the module is not loaded immediately at the import statement. Instead, a lazy proxy object is created and bound to the name. The actual module is loaded on first use of that name.

Lazy imports are only permitted at module scope. Using `lazy` inside a function, class body, or `try`/`except`/`finally` block raises a `SyntaxError`. Star imports cannot be lazy (`lazy from module import *` is a syntax error), and future statements cannot be lazy.

When using `lazy from ... import`, each imported name is bound to a lazy proxy object. The first access to any of these names triggers loading of the entire module and resolves only that specific name to its actual value. Other names remain as lazy proxies until they are accessed.

Example:

    lazy import json
    import sys

    print('json' in sys.modules)  # False - json module not yet loaded

    # First use triggers loading
    result = json.dumps({"hello": "world"})

    print('json' in sys.modules)  # True - now loaded

If an error occurs during module loading (such as `ImportError` or `SyntaxError`), it is raised at the point where the lazy import is first used, not at the import statement itself.

See PEP 810 for the full specification of lazy imports.

Ajouté dans la version 3.15.

#### 7.11.1.1. Compatibility via `__lazy_modules__`

As an alternative to using the `lazy` keyword, a module can opt into lazy loading for specific imports by defining a module-level `__lazy_modules__` variable. When present, it must be a container of fully qualified module name strings. Any regular (non-`lazy`) `import` statement at module scope whose target appears in `__lazy_modules__` is treated as a lazy import, exactly as if the `lazy` keyword had been used.

This provides a way to enable lazy loading for specific dependencies without changing individual `import` statements. This is useful when supporting Python versions older than 3.15 while using lazy imports in 3.15+:

    __lazy_modules__ = ["json", "pathlib"]

    import json     # loaded lazily (name is in __lazy_modules__)
    import os       # loaded eagerly (name not in __lazy_modules__)

    import pathlib  # loaded lazily

Relative imports are resolved to their absolute name before the lookup, so `__lazy_modules__` must always contain fully qualified module names.

For `from`-style imports, the relevant name is the module following `from`, not the names of its members:

    # In mypackage/mymodule.py
    __lazy_modules__ = ["mypackage", "mypackage.sub.utils"]

    from . import helper         # loaded lazily: . resolves to mypackage
    from .sub.utils import func  # loaded lazily: .sub.utils resolves to mypackage.sub.utils
    import json                  # loaded eagerly (not in __lazy_modules__)

Imports inside functions, class bodies, or `try`/`except`/`finally` blocks are always eager, regardless of `__lazy_modules__`.

Ajouté dans la version 3.15.

### 7.11.2. L'instruction future

Une instruction future est une directive à l'attention du compilateur afin qu'un module particulier soit compilé en utilisant une syntaxe ou une sémantique qui sera disponible dans une future version de Python où cette fonctionnalité est devenue un standard.

L'instruction future a vocation à faciliter les migrations vers les futures versions de Python qui introduisent des changements incompatibles au langage. Cela permet l'utilisation de nouvelles fonctionnalités module par module avant qu'une version n'officialise cette fonctionnalité comme un standard.

    future_stmt: "from" "__future__" "import" feature ["as" identifier]
                 ("," feature ["as" identifier])*
                 | "from" "__future__" "import" "(" feature ["as" identifier]
                 ("," feature ["as" identifier])* [","] ")"
    feature:     identifier

Une instruction future doit apparaître en haut du module. Les seules lignes autorisées avant une instruction future sont :

- la chaîne de documentation du module (si elle existe),

- des commentaires,

- des lignes vides et

- d'autres instructions future.

La seule fonctionnalité qui nécessite l'utilisation de l'instruction `future` est `annotations` (voir la PEP 563).

Toutes les fonctionnalités (feature dans la grammaire ci-dessus) autorisées par l'instruction `future` sont toujours reconnues par Python 3. Cette liste comprend `absolute_import`, `division`, `generators`, `generator_stop`, `unicode_literals`, `print_function`, `nested_scopes` et `with_statement`. Elles sont toutes redondantes car elles sont de toute manière activées ; elles ne sont conservées que par souci de compatibilité descendante.

Une instruction future est reconnue et traitée spécialement au moment de la compilation : les modifications à la sémantique des constructions de base sont souvent implémentées en générant un code différent. Il peut même arriver qu'une nouvelle fonctionnalité ait une syntaxe incompatible (tel qu'un nouveau mot réservé) ; dans ce cas, le compilateur a besoin d'analyser le module de manière différente. De telles décisions ne peuvent pas être différées au moment de l'exécution.

Pour une version donnée, le compilateur sait quelles fonctionnalités ont été définies et lève une erreur à la compilation si une instruction future contient une fonctionnalité qui lui est inconnue.

La sémantique à l'exécution est la même que pour toute autre instruction d'importation : il existe un module standard `__future__`, décrit plus loin, qui est importé comme les autres au moment où l'instruction future est exécutée.

La sémantique particulière à l'exécution dépend des fonctionnalités apportées par l'instruction future.

Notez que l'instruction suivante est tout à fait normale :

    import __future__ [as name]

Ce n'est pas une instruction future ; c'est une instruction d'importation ordinaire qui n'a aucune sémantique particulière ou restriction de syntaxe.

Code compiled by calls to the built-in functions `exec()` and `compile()` that occur in a module `M` containing a future statement will, by default, use the new syntax or semantics associated with the future statement. This can be controlled by optional arguments to `compile()` --- see the documentation of that function for details.

Une instruction future entrée à l'invite de l'interpréteur interactif est effective pour le reste de la session de l'interpréteur. Si l'interpréteur est démarré avec l'option `-i`, qu'un nom de script est passé pour être exécuté et que ce script contient une instruction future, elle est effective pour la session interactive qui démarre après l'exécution du script.

Voir aussi

PEP 236 — retour vers le `__future__`

  La proposition originale pour le mécanisme de `__future__`.

## 7.12. L'instruction `global`

    global_stmt: "global" identifier ("," identifier)*

The `global` statement causes the listed identifiers to be interpreted as globals. It would be impossible to assign to a global variable without `global`, although free variables may refer to globals without being declared global.

The `global` statement applies to the entire current scope (module, function body or class definition). A `SyntaxError` is raised if a variable is used or assigned to prior to its global declaration in the scope.

At the module level, all variables are global, so a `global` statement has no effect. However, variables must still not be used or assigned to prior to their `global` declaration. This requirement is relaxed in the interactive prompt (REPL).

Note pour les programmeurs : `global` est une directive à l'attention de l'analyseur syntaxique. Elle s'applique uniquement au code analysé en même temps que l'instruction `global`. En particulier, une instruction `global` contenue dans une chaîne ou un objet code fourni à la fonction native `exec()` n'affecte pas le code contenant cet appel et le code contenu dans un telle chaîne n'est pas affecté par une instruction `global` placée dans le code contenant l'appel. Il en est de même pour les fonctions `eval()` et `compile()`.

## 7.13. L'instruction `nonlocal`

    nonlocal_stmt: "nonlocal" identifier ("," identifier)*

When the definition of a function or class is nested (enclosed) within the definitions of other functions, its nonlocal scopes are the local scopes of the enclosing functions. The `nonlocal` statement causes the listed identifiers to refer to names previously bound in nonlocal scopes. It allows encapsulated code to rebind such nonlocal identifiers. If a name is bound in more than one nonlocal scope, the nearest binding is used. If a name is not bound in any nonlocal scope, or if there is no nonlocal scope, a `SyntaxError` is raised.

The `nonlocal` statement applies to the entire scope of a function or class body. A `SyntaxError` is raised if a variable is used or assigned to prior to its nonlocal declaration in the scope.

Voir aussi

PEP 3104 -- Accès à des noms en dehors de la portée locale

  Les spécifications pour l'instruction `nonlocal`.

Programmer's note: `nonlocal` is a directive to the parser and applies only to code parsed along with it. See the note for the `global` statement.

## 7.14. The `type` statement

    type_stmt: 'type' identifier [type_params] "=" expression

The `type` statement declares a type alias, which is an instance of `typing.TypeAliasType`.

For example, the following statement creates a type alias:

    type Point = tuple[float, float]

This code is roughly equivalent to:

    annotation-def VALUE_OF_Point():
        return tuple[float, float]
    Point = typing.TypeAliasType("Point", VALUE_OF_Point())

`annotation-def` indicates an annotation scope, which behaves mostly like a function, but with several small differences.

The value of the type alias is evaluated in the annotation scope. It is not evaluated when the type alias is created, but only when the value is accessed through the type alias's `__value__` attribute (see Lazy evaluation). This allows the type alias to refer to names that are not yet defined.

Type aliases may be made generic by adding a type parameter list after the name. See Generic type aliases for more.

`type` is a soft keyword.

Ajouté dans la version 3.12.

Voir aussi

PEP 695 - Type Parameter Syntax

  Introduced the `type` statement and syntax for generic classes and functions.