J'ai une situation comme ça ...
class Outer(object):
def some_method(self):
# do something
class Inner(object):
def __init__(self):
self.Outer.some_method() # <-- this is the line in question
Comment puis-je accéder à la Outer
méthode de la Inner
classe depuis la classe?
python
scope
nested
inner-classes
T. Stone
la source
la source
self.<original_parent_name>
et d' obtenir la classe d'origine, pas la nouvelle classe dont elles sont une sous-classe . J'espère que les gens qui liront ceci pourront visualiser ce scénario difficile et voir l'intérêt de questions comme celle-ci.Réponses:
Les méthodes d'une classe imbriquée ne peuvent pas accéder directement aux attributs d'instance de la classe externe.
Notez que ce n'est pas nécessairement le cas qu'une instance de la classe externe existe même lorsque vous avez créé une instance de la classe interne.
En fait, il est souvent déconseillé d'utiliser des classes imbriquées, car l'imbrication n'implique aucune relation particulière entre les classes interne et externe.
la source
Vous essayez d'accéder à l'instance de classe d'Outer, à partir de l'instance de classe interne. Donc, utilisez simplement la méthode factory pour créer l'instance Inner et lui transmettre l'instance externe.
la source
peut-être que je suis en colère mais cela semble très facile en effet - le truc est de faire de votre classe intérieure une méthode de la classe extérieure ...
De plus ... "self" n'est utilisé que par convention, vous pouvez donc faire ceci:
On pourrait objecter que vous ne pouvez pas créer cette classe interne à partir de l'extérieur de la classe externe ... mais ce n'est pas vrai:
puis, quelque part à des kilomètres:
même pousser un peu le bateau et étendre cette classe interne (NB pour que super () fonctionne, vous devez changer la signature de classe de mooble en "class mooble (object)"
plus tard
mrh1997 a soulevé un point intéressant sur l'héritage non commun des classes internes fournies à l'aide de cette technique. Mais il semble que la solution soit assez simple:
la source
Voulez-vous utiliser l'héritage plutôt que d'imbriquer des classes comme celle-ci? Ce que vous faites n'a pas beaucoup de sens en Python.
Vous pouvez accéder à la
Outer
méthode some_method en vous référant simplementOuter.some_method
aux méthodes de la classe interne, mais cela ne fonctionnera pas comme prévu. Par exemple, si vous essayez ceci:... vous obtiendrez une TypeError lors de l'initialisation d'un
Inner
objet, carOuter.some_method
s'attend à recevoir uneOuter
instance comme premier argument. (Dans l'exemple ci-dessus, vous essayez essentiellement d'appeler ensome_method
tant que méthode de classe deOuter
.)la source
Vous pouvez facilement accéder à la classe externe en utilisant la métaclasse: après la création de la classe externe, vérifiez son attribut dict pour toutes les classes (ou appliquez toute logique dont vous avez besoin - la mienne est juste un exemple trivial) et définissez les valeurs correspondantes:
En utilisant cette approche, vous pouvez facilement lier et référencer deux classes entre elles.
la source
J'ai créé du code Python pour utiliser une classe externe de sa classe interne , basée sur une bonne idée d'une autre réponse à cette question. Je pense que c'est court, simple et facile à comprendre.
Le code principal, "prêt pour la production" (sans commentaires, etc.). N'oubliez pas de remplacer toutes les valeurs entre crochets angulaires (par exemple
<x>
) par la valeur souhaitée.Explication du fonctionnement de cette méthode (les étapes de base):
Créez une fonction nommée
_subclass_container
pour agir comme un wrapper pour accéder à la variableself
, une référence à la classe de niveau supérieur (à partir du code exécuté à l'intérieur de la fonction).Créez une variable nommée
_parent_class
qui est une référence à la variableself
de cette fonction, à laquelle les sous-classes de_subclass_container
peuvent accéder (évite les conflits de nom avec d'autresself
variables dans les sous-classes).Renvoie la sous-classe / sous-classe sous forme de dictionnaire / liste afin que le code appelant la
_subclass_container
fonction puisse accéder aux sous-classes à l'intérieur.Dans la
__init__
fonction à l'intérieur de la classe de niveau supérieur (ou partout où cela est nécessaire), recevez les sous-classes retournées de la fonction_subclass_container
dans la variablesubclasses
.Attribuez des sous-classes stockées dans la
subclasses
variable aux attributs de la classe de niveau supérieur.Quelques conseils pour faciliter les scénarios:
Rendre le code pour affecter les sous-classes à la classe de niveau supérieur plus facile à copier et à utiliser dans les classes dérivées de la classe de niveau supérieur dont la
__init__
fonction a été modifiée:Insérer avant la ligne 12 dans le code principal:
Insérez ensuite dans cette fonction les lignes 5-6 (du code principal) et remplacez les lignes 4-7 par le code suivant:
Rendre possible l'attribution de sous-classes à la classe de niveau supérieur lorsqu'il existe de nombreuses / quantités inconnues de sous-classes.
Remplacez la ligne 6 par le code suivant:
Exemple de scénario où cette solution serait utile et où le nom de classe de niveau supérieur devrait être impossible à obtenir:
Une classe, nommée "a" (
class a:
) est créée. Il a des sous-classes qui doivent y accéder (le parent). Une sous-classe est appelée "x1". Dans cette sous-classe, le codea.run_func()
est exécuté.Ensuite, une autre classe, nommée "b" est créée, dérivée de la classe "a" (
class b(a):
). Après cela, du code s'exécuteb.x1()
(appelant la sous-fonction "x1" de b, une sous-classe dérivée). Cette fonction s'exécutea.run_func()
en appelant la fonction "run_func" de la classe "a", et non la fonction "run_func" de son parent, "b" (comme il se doit), car la fonction qui a été définie dans la classe "a" est définie pour faire référence à la fonction de la classe "a", car c'était son parent.Cela poserait des problèmes (par exemple si la fonction
a.run_func
a été supprimée) et la seule solution sans réécrire le code dans la classea.x1
serait de redéfinir la sous-classex1
avec du code mis à jour pour toutes les classes dérivées de la classe "a" ce qui serait évidemment difficile et ne vaut pas la peine il.la source
J'ai trouvé ça .
Ajusté pour répondre à votre question:
Je suis sûr que vous pouvez en quelque sorte écrire un décorateur pour ceci ou quelque chose
Related: Quel est le but des classes internes de python?
la source
Une autre possibilité:
la source
Expansion sur la pensée convaincante de @ tsnorri, selon laquelle la méthode externe peut être une méthode statique :
Maintenant, la ligne en question devrait fonctionner au moment où elle est effectivement appelée.
La dernière ligne du code ci-dessus donne à la classe Inner une méthode statique qui est un clone de la méthode statique Outer.
Cela tire parti de deux fonctionnalités Python, à savoir que les fonctions sont des objets et la portée est textuelle .
... ou classe actuelle dans notre cas. Ainsi, les objets "locaux" à la définition de la classe externe (
Inner
etsome_static_method
) peuvent être référencés directement dans cette définition.la source
Quelques années de retard à la fête ... mais pour développer
@mike rodent
la réponse merveilleuse de 's, j'ai donné mon propre exemple ci-dessous qui montre à quel point sa solution est flexible et pourquoi elle aurait dû (ou aurait dû être) acceptée répondre.Python 3.7
Production:
Encore une fois, une réponse merveilleuse, des accessoires à vous mike!
la source
C'est trop simple:
Contribution:
Production
classe A func1
classe B func1
la source
func1
. Et, tout aussi amusant, vous créez unA
à l'intérieur du constructeur deB
, qui n'est absolument PAS l'A
objet de classe externe de ce particulierB
.