class Outer(object):
outer_var = 1
class Inner(object):
@property
def inner_var(self):
return Outer.outer_var
Ce n'est pas tout à fait la même chose que des choses similaires fonctionnent dans d'autres langues et utilisent la recherche globale au lieu d'étendre l'accès à outer_var
. (Si vous modifiez l'objet Outer
auquel le nom est lié, ce code utilisera cet objet la prochaine fois qu'il sera exécuté.)
Si vous souhaitez à la place que tous les Inner
objets aient une référence à un Outer
car outer_var
est vraiment un attribut d'instance:
class Outer(object):
def __init__(self):
self.outer_var = 1
def get_inner(self):
return self.Inner(self)
# "self.Inner" is because Inner is a class attribute of this class
# "Outer.Inner" would also work, or move Inner to global scope
# and then just use "Inner"
class Inner(object):
def __init__(self, outer):
self.outer = outer
@property
def inner_var(self):
return self.outer.outer_var
Notez que l'imbrication de classes est quelque peu rare en Python et n'implique pas automatiquement une sorte de relation spéciale entre les classes. Vous feriez mieux de ne pas nicher. (Vous pouvez toujours définir un attribut de classe sur Outer
pour Inner
, si vous voulez.)
Outer
est recherchée à nouveau à chaque fois que vous le faitesInner.inner_var
. Donc, si vous reliez le nomOuter
à un nouvel objet,Inner.inner_var
commencera à renvoyer ce nouvel objet.Je pense que vous pouvez simplement faire:
Le problème que vous avez rencontré est dû à ceci:
Ce qui précède signifie:
un corps de fonction est un bloc de code et une méthode est une fonction, alors les noms définis à partir du corps de fonction présent dans une définition de classe ne s'étendent pas au corps de fonction.
Paraphrasant ceci pour votre cas:
une définition de classe est un bloc de code, alors les noms définis à partir de la définition de classe interne présente dans une définition de classe externe ne s'étendent pas à la définition de classe interne.
la source
[a + i for i in range(10)]
lie avec succès Ab à la liste attendue [42..51].list(a + i for i in range(10))
estlist((a + i for i in range(10)))
c'est - à - direlist(a_generator)
. Ils disent qu'un générateur est implémenté avec une portée similaire à celle des fonctions.list(...)
appel ni la compréhension ne fonctionnent en Python 3. La documentation de Py3 est également légèrement différente reflétant cela. Il dit maintenant: " La portée des noms définis dans un bloc de classe est limitée au bloc de classe; elle ne s'étend pas aux blocs de code des méthodes - cela inclut les compréhensions et les expressions génératrices puisqu'elles sont implémentées en utilisant une portée de fonction. " (C'est moi qui souligne ).Vous feriez peut-être mieux de ne pas utiliser de classes imbriquées. Si vous devez imbriquer, essayez ceci:
Ou déclarez les deux classes avant de les imbriquer:
(Après cela, vous pouvez
del InnerClass
si vous en avez besoin.)la source
Solution la plus simple:
Cela vous oblige à être explicite, mais ne demande pas beaucoup d'efforts.
la source
En Python, les objets mutables sont passés comme référence, vous pouvez donc passer une référence de la classe externe à la classe interne.
la source
__del__
méthode, le garbage collector ne pourra pas gérer le cycle de référence et les objets entreront dansgc.garbage
. Le code ci-dessus, tel quel, n'est cependant pas problématique. La façon de gérer cela consiste à utiliser une référence faible . Vous pouvez lire la documentation sur lowref (2.7) ou lowref (3.5)Toutes les explications se trouvent dans la documentation Python Le didacticiel Python
Pour votre première erreur
<type 'exceptions.NameError'>: name 'outer_var' is not defined
. L'explication est:cité dans The Python Tutorial 9.4
Pour votre deuxième erreur
<type 'exceptions.NameError'>: name 'OuterClass' is not defined
cité dans The Python Tutorial 9.3.1
Alors quand vous essayez
inner_var = Outerclass.outer_var
, leQuterclass
n'a pas encore été créé, c'est pourquoiname 'OuterClass' is not defined
Une explication plus détaillée mais fastidieuse de votre première erreur:
cité de Learning.Python (5e) .Mark.Lutz
la source