python instance de classe les variables et les variables de classe
Je vais avoir un problème de compréhension de la façon dont la classe /instance des variables en Python. Je ne comprends pas pourquoi quand j'ai essayer ce code, la variable de liste semble être une variable de classe
class testClass():
list = []
def __init__(self):
self.list.append('thing')
p = testClass()
print p.list
f = testClass()
print f.list
De sortie:
['thing']
['thing', 'thing']
et quand je fais cela il semble être une variable d'instance
class testClass():
def __init__(self):
self.list = []
self.list.append('thing')
p = testClass()
print p.list
f = testClass()
print f.list
De sortie:
['thing']
['thing']
- Si je comprends bien, vous demandez la logique derrière le design particulier de la décision concernant Python syntaxe. Pour de telles questions, la meilleure réponse est "parce qu'il s'adapte à la langue de l'esprit", ou plus flagrante: "demander à son créateur".
- ok, donc les variables sont des variables de classe par défaut, c'est la où ma confusion découle, qui aurait été à ma question, ne les variables par défaut pour les variables de classe
- Non, les variables ne sont PAS variables de classe par défaut. En Python, vous ne déclarez pas varables. D'ailleurs, ils ne sont pas réellement des variables (python est un variableless lanuage), juste des noms. Et vous ne déclarez pas ou assing noms, vous les lier à un objet. Et chaque objet de la durée de fonctionnement est un dictionnaire de noms de l'objet. Et même si les deux objets sont de la même classe, ils peuvent être très différents dictionnaires.
- Dans ton premier exemple, vous avez créé un véritable ressource partagée entre tous les membres de la classe
MyClass
. Vous ensuite à privatiser le contenu de l'une des caractéristiques communes à chaque membre de la classeMyClass
. - double possible de Comment puis-je éviter d'avoir Python classe de données partagées entre les instances?
- Le même problème se produit en Javascript pour des raisons un peu différentes. En tant que programmeur javascript je ne suis pas surpris, quand j'ai commencé à apprendre le Python. En fait je m'y attendais, c'est comment j'ai trouvé ce post.
Vous devez vous connecter pour publier un commentaire.
C'est parce que de la façon Python résout les noms avec l'
.
. Lorsque vous écrivezself.list
l'exécution Python essaie de résoudre lelist
nom d'abord par chercher dans l'instance de l'objet, et s'il ne s'y trouve pas, puis dans l'instance de classe.Regardons vers elle, étape par étape
list
nom de l'objetself
?list
nom dans la classe de l'instance de l'objetself
?Mais lorsque vous liez un nom, les choses sont différentes:
list
nom de l'objetself
?Donc, c'est toujours une variable d'instance.
Votre premier exemple crée un
list
dans l'instance de classe, comme c'est l'étendue active à l'époque (pas deself
n'importe où). Mais votre deuxième exemple crée unlist
explicitement dans le champ d'application deself
.Plus intéressant serait l'exemple:
À imprimer:
Le moment où vous supprimez le nom de l'instance le nom de la classe est visible à travers le
self
de référence.self.list[]
à l'extérieur de init, ce qui est logique, mais est-il un moyen?__new__
et de créer de là, mais c'est vraiment moche comme c'est pas ce que__new__
est vraiment pour, et c'est pas vraiment mieux que de les créer dans__init__
. Ce qui, prie-dire, pensez-vous que vous avez besoin de cette capacité pour? Vous pouvez créer un méta-classe qui surcharges__new__
à regarder à travers la classe dict et de copier les choses à l'instance dict. Mais c'est vraiment est laid.p.list = []
, en dehors de toute fonction, la portée mondiale et le tout fonctionne.class
construire est juste sucre syntaxique pour un tas de tâches pour les membres d'uneclass
instance. La chose la plus proche à une déclaration d'affectation de la classe__slots__
variable pour un nouveau style de classe.Python a des règles intéressantes à propos de la recherche des noms. Si vous voulez vraiment plier votre tête, essayez ce code:
Cela donnera à chaque occurrence d'une variable appelée
l
qui masque la variable de classel
. Vous serez toujours en mesure d'obtenir à la variable de classe si vous neself.__class__.l
.La je pense que c'est ce... à Chaque fois que vous ne
instance.variable
(même pour les noms de méthode, ils sont juste des variables qui les valeurs se trouvent être des fonctions), il le recherche dans l'exemple du dictionnaire. Et si elle ne peut pas le trouver là, il tente de le rechercher dans l'instance de la classe' dictionnaire. C'est seulement si la variable est "lire". Si il est affecté, il crée toujours une nouvelle entrée dans l'instance dictionnaire.Dans votre premier exemple,
list
est un attribut de la classe, partagée par toutes les instances de celui-ci. Cela signifie que vous pouvez même y accéder sans avoir un objet de typetestClass
:Mais tous les objets partagent le
list
attribut à la classe des uns et des autres:Lorsque vous instancier une classe,
__init__
méthode est exécutée automatiquement.Dans le premier cas, votre liste est un attribut de classe est partagée par toutes ses instances. Vous avez deux chose " est parce que vous avez ajouté un quand instantitating
p
et un autre lorsqu'il est instanciéf
(le premier était déjà annexé au premier appel).