Une courte note de la série "Vous avez été prévenu".
Passer des langages de programmation classiques à Python apporte beaucoup de surprises.
Lisez la documentation:
De manière générale, les variables d'instance sont pour les données propres à chaque instance et les variables de classe sont pour les attributs et les méthodes partagés par toutes les instances de la classe
Essayons de jouer
class Vessel:
Créez deux objets, vérifiez les valeurs de
tous les attributs:
Iowa = Vessel("Iowa") Drum=Vessel("Drum") printAttr(Iowa, Drum) >>name=Iowa vtype=boat __class__.vtype=boat >>name=Drum vtype=boat __class__.vtype=boat
Jusqu'à présent, comme prévu.
Essayons de changer vtype: cela peut être fait de deux façons, qui sont essentiellement juste une syntaxe différente de la même
Vessel.vtype = "USS boat" printAttr(Iowa, Drum) >>name=Iowa vtype=USS boat __class__.vtype=USS boat >>name=Drum vtype=USS boat __class__.vtype=USS boat Iowa.__class__.vtype = 'USS WW2 Boat' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat
Et encore une fois, tout est en ordre.
Essayons maintenant de faire de même à travers l'attribut de l'objet.
Drum.vtype = 'submarine' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=submarine __class__.vtype=USS WW2 Boat
Et voici la première surprise: malgré le fait que vtype est un attribut d'une classe, il devient soudainement un attribut d'un objet.
Vérifier:
Vessel.vtype = "NAVY Museum" >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=submarine __class__.vtype=NAVY Museum
Et si ...
del Drum.vtype >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=NAVY Museum __class__.vtype=NAVY Museum
Et encore un attribut de classe.
L'expression suivante ne passe plus
del Drum.vtype printAttr(Iowa, Drum) del Drum.vtype AttributeError: vtype
Et le dernier exemple émulant des substitutions de classe et supprimant l'attribut vtype.
Drum.vtype = 'submarine' del Vessel.vtype printAttr(Iowa, Drum) >>name=Iowa >>name=Drum vtype=submarine
Si vous commencez à gérer l'espace de noms, ce comportement devient compréhensible.
Cependant, pour les programmeurs qui travaillaient auparavant avec des langages normaux, cela semble au moins étrange. Et si nous parlons de grands projets qui sont soutenus par plusieurs générations de développeurs, cela peut se révéler être un échec des délais, etc.
Compte tenu du concept de Python selon lequel tout est ouvert à tous, pourquoi ne pas accéder aux attributs "cool" uniquement via __class__ ou son analogue. À mon avis, cela protégerait au moins en quelque sorte contre les surprises et me ferait réfléchir 10 fois avant d'attribuer quelque chose aux attributs de classe au niveau de l'objet.
Mise à jour: Text PrintAttr
def printAttr(*o): for a in o: print(a)