Maison >développement back-end >Tutoriel Python >Pourquoi ne puis-je pas accéder aux variables de classe directement à partir des compréhensions de liste dans Python 3 ?

Pourquoi ne puis-je pas accéder aux variables de classe directement à partir des compréhensions de liste dans Python 3 ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-18 09:09:10163parcourir

Why Can't I Access Class Variables Directly from List Comprehensions in Python 3?

Accès aux variables de classe à partir de compréhensions de liste dans les définitions de classe

Dans Python 2, l'accès aux variables de classe à partir d'une compréhension de liste dans la définition de classe était possible. Cependant, dans Python 3 et versions ultérieures, cela n'est pas autorisé en raison de restrictions de portée. La portée de la classe est traitée séparément de la portée des compréhensions et des autres fonctions et, par conséquent, l'accès aux variables de classe à partir d'une compréhension en utilisant des noms n'est pas autorisé.

Par exemple, le code suivant en Python 2 fonctionnerait :

class Foo:
    x = 5
    y = [x for i in range(1)]

Cependant, en Python 3, cela entraînerait une erreur :

NameError: name 'x' is not defined

Pourquoi et comment la portée La restriction fonctionne

La raison de cette restriction est due à la façon dont Python gère les étendues. Lors de l’évaluation d’une compréhension de liste dans une définition de classe, Python crée une nouvelle portée pour cette compréhension. Cette nouvelle portée n'inclut pas la portée de la classe, donc toutes les variables définies dans la portée de la classe ne sont pas visibles dans la compréhension.

Les compréhensions, les expressions génératrices et les fonctions lambda ont toutes leurs propres portées isolées, ce qui signifie qu'elles ne peuvent pas accéder directement aux variables à partir de la fonction englobante ou de la portée de la classe. Il s'agit d'une mesure de sécurité qui empêche les modifications involontaires des variables dans la portée englobante.

Solutions de contournement

Il existe quelques solutions de contournement à cette restriction :

  1. Utiliser une fonction temporaire : Vous pouvez définir une fonction au sein de la classe qui transmet explicitement la variable de classe au compréhension :
class Foo:
    x = 5

    def get_y(self, x):
        return [x for i in range(1)]

    y = get_y(x)
  1. Utiliser Nonlocal : Ce mot-clé peut être utilisé pour demander à une fonction dans une portée imbriquée de modifier une variable dans une portée englobante :
class Foo:
    x = 5

    def get_y():
        nonlocal x
        return [x for i in range(1)]

    y = get_y()
  1. Utiliser une variable d'instance : Au lieu de en stockant le résultat de compréhension sur la classe elle-même, vous pouvez le stocker sur une instance :
class Foo:
    def __init__(self):
        self.y = [self.x for i in range(1)]
  1. Utiliser un attribut de fonction : Semblable à l'utilisation d'une fonction temporaire, vous pouvez également définir un attribut de fonction qui stocke la variable de classe :
class Foo:
    x = 5

    @classmethod
    def get_y(cls):
        y = [cls.x for i in range(1)]
        return y

Foo.y = Foo.get_y()

Il est important de noter que même si ces solutions de contournement permettent vous pouvez accéder aux variables de classe à partir des compréhensions, elles introduisent une complexité supplémentaire à votre code. Réfléchissez attentivement à l'approche la plus adaptée à vos besoins spécifiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn