121 votes

La portée des classes imbriquées ?

J'essaie de comprendre la portée des classes imbriquées en Python. Voici mon exemple de code :

class OuterClass:
    outer_var = 1
    class InnerClass:
        inner_var = outer_var

La création de la classe ne se termine pas et je reçois l'erreur :

<type 'exceptions.NameError'>: name 'outer_var' is not defined

Essayer inner_var = Outerclass.outer_var ne fonctionne pas. J'obtiens :

<type 'exceptions.NameError'>: name 'OuterClass' is not defined

J'essaie d'accéder aux données statiques outer_var de InnerClass .

Y a-t-il un moyen de le faire ?

1voto

Andy Guo Points 47

Toutes les explications se trouvent dans Documentation Python Le tutoriel Python

Pour votre première erreur <type 'exceptions.NameError'>: name 'outer_var' is not defined . L'explication est la suivante :

Il n'existe pas de raccourci pour référencer les attributs de données (ou d'autres méthodes !) à l'intérieur des méthodes. Je trouve que cela augmente la lisibilité des méthodes : il n'y a aucune chance de confondre les variables locales et les variables d'instance en parcourant une méthode.

cité par Le tutoriel Python 9.4

Pour votre deuxième erreur <type 'exceptions.NameError'>: name 'OuterClass' is not defined

Lorsqu'une définition de classe est quittée normalement (par la fin), un objet de classe est créé.

cité par Le tutoriel Python 9.3.1

Donc quand vous essayez inner_var = Outerclass.outer_var le Quterclass n'a pas encore été créée, c'est pourquoi name 'OuterClass' is not defined

Une explication plus détaillée mais fastidieuse pour votre première erreur :

Bien que les classes aient accès à l'étendue des fonctions englobantes, elles n'agissent pas en tant que scopes d'inclusion pour le code imbriqué dans la classe : Python recherche les fonctions englobantes pour les noms référencés, mais jamais dans les classes englobantes. En d'autres termes, une classe est une portée locale et a accès aux portées locales englobantes, mais elle ne sert pas de portée locale englobante à du code imbriqué supplémentaire.

cité par Apprendre.Python(5ème).Mark.Lutz

0voto

ron Points 1
class c_outer:
    def __init__(self, name:str='default_name'):
        self._name = name
        self._instance_lst = list()
        self._x = self.c_inner()

    def get_name(self):
        return(self._name)

    def add_inner_instance(self,name:str='default'):
        self._instance_lst.append(self.c_inner(name))

    def get_instance_name(self,index:int):
        return(self._instance_lst[index].get_name())

    class c_inner:
        def __init__(self, name:str='default_name'):
            self._name = name
        def get_name(self):
            return(self._name)

outer = c_outer("name_outer")

outer.add_inner_instance("test1")
outer.add_inner_instance("test2")
outer.add_inner_instance("test3")
inner_1 = outer.c_inner("name_inner1")
inner_2 = outer.c_inner("name_inner2")
inner_3 = outer.c_inner("name_inner3")

print(outer.get_instance_name(index=0))
print(outer.get_instance_name(1))
print(outer._instance_lst[2]._name
print(outer.get_name())
print(inner_1.get_name())
print(inner_2.get_name())

test1 test2 test3 nom_outer nom_inner1 nom_inner2 nom_inner3

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X