J'essaie de comprendre comment l'héritage de classe fonctionne dans Python 3, en particulier comment les champs privés interagissent avec les méthodes locales et héritées. Voici quelques exemples pour illustrer le problème.Python3: héritage de classe et champs privés
En premier lieu, si une var
variable dans la superclasse est publique, toute méthode dans la sous-classe sera également en mesure de le modifier:
class Superclass:
var = 1
def getVar(self):
print(self.var)
class Subclass(Superclass):
def __init__(self):
self.var = 123
my_object = Subclass()
my_object.getVar() # outputs 123
La même chose est pas vrai si la __var
variable dans la superclasse est privé, toute méthode héritée ignorera modifications effectuées par le Sous-classe:
class Superclass:
__var = 1
def getVar(self):
print(self.__var)
class Subclass(Superclass):
def __init__(self):
self.__var = 123
my_object = Subclass()
my_object.getVar() # outputs 1!
méthodes locales dans la sous-classe peuvent le modifier:
class Superclass:
__var = 1
class Subclass(Superclass):
def __init__(self):
self.__var = 123
def getVar(self):
print(self.__var)
my_object = Subclass()
my_object.getVar() # outputs 123
Mais afin d'utiliser une méthode héritée de la valeur modifiée, je dois utiliser self._Superclass__var
au lieu de self.__var
dans la sous-classe:
class Superclass:
__var = 1
def getVar(self):
print(self.__var)
class Subclass(Superclass):
def __init__(self):
self._Superclass__var = 123
my_object = Subclass()
my_object.getVar() # outputs 123
Pourquoi est-ce le cas? Les champs privés ne sont-ils pas hérités par les sous-classes et, par conséquent, la variable self.__var
à l'intérieur du Subclass
ne pointe PAS à la même valeur que la variable self.__var
à l'intérieur de Superclass
?
Il n'y a pas de champs privés en Python. Si vous préfixez un nom d'attribut avec '__', vous appelez le nom mangling, où le nom de la classe« owning »est automatiquement inséré afin d'éviter que les noms d'attributs ne soient en conflit dans les sous-classes. Cela ne vous empêche pas d'y accéder, il vous suffit d'inclure le nom de la classe propriétaire. Voir https://docs.python.org/3/tutorial/classes.html#private-variables – kindall
Il n'y a pas de champs privés * en Python. C'est votre malentendu fondamental. Vous utilisez double-underscore name-mangling, qui empêche les collisions de noms dans les classes héritées, pas pour empêcher l'accès.En aparté, j'espère que vous réalisez que vous définissez des * variables de niveau classe *, équivalentes à des "variables statiques" dans d'autres langages, plutôt que des variables d'instance. –
Je pense qu'il vaut la peine d'ajouter cette précision en guise de réponse, car c'est une bonne question pour les personnes venant d'horizons différents. –