Python dérivée de la classe et de la classe de base attributs?
Il semble y avoir aucune bonne documentation en ligne sur ceci:
Si je fais une classe dérivée, il sera automatiquement tous les attributs de la classe de base? Mais ce qui est le BaseClass.__init()
, vous devez également faire d'autres méthodes de classe de base? Ne BaseClass.__init__()
besoin d'arguments? Si vous avez des arguments pour votre classe de base __init__()
, ils sont également utilisés par la classe dérivée, vous devez définir explicitement les arguments de la dérivée de classe __init__()
, ou de les mettre à BaseClass.__init__()
à la place?
OriginalL'auteur liamel1i | 2011-06-18
Vous devez vous connecter pour publier un commentaire.
Si vous mettez en œuvre
__init__
dans une classe dérivée de BaseClass, puis il va remplacer l'héritée__init__
méthode et doncBaseClass.__init__
ne sera jamais appelé. Si vous avez besoin d'appeler le__init__
méthode pour BaseClass (comme c'est normalement le cas), alors c'est à vous de le faire, et sa fait explicitement en appelantBaseClass.__init__
, normalement à partir de l'intérieur de la nouvellement mis en œuvre__init__
méthode.Ce sera la cause de l'erreur suivante:
Donc, le
do_something
méthode a été hérité comme prévu, mais cette méthode nécessite l'attributa
avoir été réglée, il ne l'est jamais car__init__
a également été remplacé. Nous contourner ce en appelant explicitementFoo.__init__
de l'intérieurBar.__init__
.qui imprime
10
comme prévu.Foo.__init__
dans ce cas s'attend à ce qu'un seul argument qui est une instance deFoo
(qui par convention est appeléeself
).Normalement, lorsque vous appelez une méthode sur une instance d'une classe, l'instance de classe est passé automatiquement en tant que premier argument. Méthodes sur une instance d'une classe sont appelées les méthodes liées.
bar.do_something
est un exemple d'une méthode liée (et vous remarquerez qu'il est appelé sans arguments).Foo.__init__
est un indépendant méthode parce qu'il n'est pas attaché à une instance particulière deFoo
, de sorte que le premier argument, une instance deFoo
, doit être transmis de manière explicite.Dans notre cas, nous passons
self
àFoo.__init__
, qui est l'instance deBar
a été passé à la__init__
méthode dansBar
. DepuisBar
hérite deFoo
, les instances deBar
sont également des instances deFoo
, donc en passantself
àFoo.__init__
est autorisé.Il est probable que la classe héritant de l'exige ou accepte des arguments plus que juste une instance de la classe. Ces sujets sont traités, comme vous le feriez avec n'importe quelle méthode que vous appelez à partir de l'intérieur de
__init__
:qui imprime
20
.Si vous essayez de mettre en œuvre une interface entièrement expose tous les arguments d'initialisation de la classe de base par le biais de votre héritant de la classe, vous en aurez besoin pour le faire explicitement. Ceci est généralement fait avec l' *args et **kwargs arguments (les noms sont par convention), qui sont des espaces réservés pour tous reste des arguments qui ne sont pas explicitement nommé. L'exemple suivant utilise tout ce que j'ai abordés:
Dans ce cas, l'argument
c
est fixé à 40, comme c'est le premier argument deBar.__init__
. Le deuxième argument est ensuite incorporé dans les variablesargs
etkwargs
(*et ** est une syntaxe spécifique qui dit que l'élargissement de la liste/n-uplet ou un dictionnaire pour séparer les arguments lors du passage d'une fonction/méthode), et est transmis àFoo.__init__
.Cet exemple rend le point que tout écrasé méthode doit être appelée explicitement si c'est ce qui est nécessaire (comme
do_something
est dans ce cas).Un point final, vous verrez souvent
super(ChildClass, self).method()
(oùChildClass
est arbitraire de la classe enfant) utilisé au lieu d'un appel à laBaseClass
méthode explicite. Discussion desuper
est une toute autre question, mais il suffit de dire, dans ces cas, il est généralement utilisé pour faire exactement ce qui est fait en appelantBaseClass.method(self)
. Brièvement,super
délégués de l'appel de méthode à la classe suivante dans la méthode de résolution de l'ordre - la MRO (ce qui, dans l'héritage simple est la classe mère). Voir la documentation sur super pour plus d'info.OriginalL'auteur Henry Gomersall
Les attributs de classe, oui. Exemple attributs, pas (tout simplement parce qu'ils n'existent pas lorsque la classe est créée), à moins qu'il n'y a pas
__init__
dans la classe dérivée, auquel cas celle de base sera appelée à la place, et permet de définir les attributs d'instance.Dépend de la classe et de ses
__init__
signature. Si vous êtes en appelant explicitementBase.__init__
dans la classe dérivée, vous aurez au moins besoin de passerself
comme premier argument. Si vous avezalors il est assez évident que pas d'autres arguments sont acceptées par le
__init__
. Si vous avez de l'ensuite vous devez passer
argument
lors de l'appel de la base de__init__
. Pas la science de fusée.Encore une fois, si la classe dérivée n'a pas
__init__
, la base de l'un sera utilisé à la place.Dans d'autres cas, vous devez prendre soin d'elle en quelque sorte. Si vous utilisez
*args, **kwargs
et juste passer des arguments non modifiée pour la classe de base, ou une copie de la classe de base de la signature, ou à fournir des arguments d'ailleurs, dépend de ce que vous essayez d'accomplir.OriginalL'auteur Cat Plus Plus