web-dev-qa-db-fra.com

Portée du bloc dans Python

Lorsque vous codez dans d'autres langues, vous créerez parfois une portée de bloc, comme ceci:

statement
...
statement
{
    statement
    ...
    statement
}
statement
...
statement

Un but (parmi tant d'autres) est d'améliorer la lisibilité du code: montrer que certaines instructions forment une unité logique ou que certaines variables locales sont utilisées uniquement dans ce bloc.

Existe-t-il une façon idiomatique de faire la même chose en Python?

76
Johan Råde

Non, il n'y a pas de prise en charge linguistique pour la création de l'étendue de bloc.

Les constructions suivantes créent une portée:

  • module
  • classe
  • fonction (incl. lambda)
  • expression de générateur
  • compréhensions (dict, set, list (in Python 3.x))
66
ThomasH

La manière idiomatique dans Python est de garder vos fonctions courtes. Si vous pensez que vous en avez besoin, refactorisez votre code! :)

Python crée une nouvelle portée pour chaque module, classe, fonction, expression de générateur, compréhension de dict, compréhension d'ensemble et dans Python 3.x également pour chaque compréhension de liste. En dehors de ceux-ci, il n'y a pas d'imbrication portées à l'intérieur des fonctions.

35
Sven Marnach

Vous pouvez faire quelque chose de similaire à une portée de bloc C++ dans Python en déclarant une fonction à l'intérieur de votre fonction, puis en l'appelant immédiatement. Par exemple:

def my_func():
    shared_variable = calculate_thing()

    def do_first_thing():
        ... = shared_variable
    do_first_thing()

    def do_second_thing():
        foo(shared_variable)
        ...
    do_second_thing()

Si vous ne savez pas pourquoi vous pourriez vouloir faire cela, alors cette vidéo pourrait vous convaincre.

Le principe de base est d'étendre tout aussi étroitement que possible sans introduire de "déchets" (types/fonctions supplémentaires) dans une étendue plus large que ce qui est absolument nécessaire - Rien d'autre ne veut utiliser la méthode do_first_thing() par exemple pour ne doit pas être délimité en dehors de la fonction appelante.

13
Ben

Je suis d'accord qu'il n'y a pas de portée de bloc. Mais un endroit dans python 3 le fait SEMBLER comme s'il avait une portée de bloc.

que s'est-il passé qui a donné ce look? Cela fonctionnait correctement dans python 2. mais pour arrêter les fuites variables dans python 3, ils ont fait cette astuce et ce changement donne l'impression que a une portée de bloc ici.

Laissez-moi expliquer.


Selon l'idée de portée, lorsque nous introduisons des variables portant le même nom dans la même portée, sa valeur doit être modifiée.

c'est ce qui se passe dans python 2

>>> x = 'OLD'
>>> sample = [x for x in 'NEW']
>>> x
'W'

Mais dans python 3 même si la variable du même nom est introduite, elle ne remplace pas, la compréhension de la liste agit comme un bac à sable pour une raison quelconque et semble créer une nouvelle portée dedans.

>>> x = 'OLD'
>>> sample = [x for x in 'NEW']
>>> x
'OLD'

et cette réponse va à l'encontre de la réponse du répondeur @ Thomas ( Le seul moyen de créer une portée est des fonctions, des classes ou des modules parce que cela ressemble comme un autre endroit pour créer une nouvelle portée.

11
Harish Kayarohanam