Je suis à peu près ignorant OOP jargon et concepts. Je sais conceptuellement ce qu'est un objet, et que les objets ont des méthodes. Je comprends même qu'en python, les classes sont des objets! C'est cool, je je ne sais pas ce que ça veut dire. Ça ne clique pas avec moi.
J'essaie actuellement de comprendre quelques réponses détaillées qui, à mon avis, éclaireront ma compréhension du python:
Dans la première réponse, l'auteur utilise le code suivant comme exemple:
>>> class Bank(): # let's create a bank, building ATMs
... crisis = False
... def create_atm(self) :
... while not self.crisis :
... yield "$100"
Je ne vois pas immédiatement ce que self
pointe. C'est certainement un symptôme de ne pas comprendre les cours, sur lequel je travaillerai à un moment donné. Pour clarifier, en
>>> def func():
... for i in range(3):
... print i
Je comprends que i
pointe vers un élément de la liste range(3)
qui, puisqu'il est dans une fonction, n'est pas global. Mais qu'est-ce que self
"pointe vers"?
Je vais d'abord essayer de dissiper une certaine confusion sur les classes et les objets. Regardons ce bloc de code:
>>> class Bank(): # let's create a bank, building ATMs
... crisis = False
... def create_atm(self) :
... while not self.crisis :
... yield "$100"
Le commentaire y est un peu trompeur. Le code ci-dessus ne "crée" pas de banque. Il définit ce qu'est une banque. Une banque est quelque chose qui a une propriété appelée crisis
et une fonction create_atm
. C'est ce que dit le code ci-dessus.
Créons maintenant une banque:
>>> x = Bank()
Là, x
est maintenant une banque. x
a une propriété crisis
et une fonction create_atm
. L'appel de x.create_atm();
dans python est identique à l'appel de Bank.create_atm(x);
, donc maintenant self
fait référence à x
. Si vous ajoutez une autre banque appelée y
, appelant y.create_atm()
saura regarder la valeur de crise de y
, pas de x
car dans cette fonction self
fait référence à y
.
self
n'est qu'une convention de dénomination, mais il est très bon de s'y tenir. Il convient tout de même de souligner que le code ci-dessus équivaut à:
>>> class Bank(): # let's create a bank, building ATMs
... crisis = False
... def create_atm(thisbank) :
... while not thisbank.crisis :
... yield "$100"
Cela peut vous aider à considérer la syntaxe d'invocation de obj.method(arg1, arg2)
comme un sucre purement syntaxique pour appeler method(obj, arg1, arg2)
(sauf que method
est recherché via le type de obj
, et n'est pas global).
Si vous le voyez de cette façon, obj
est le premier argument de la fonction, qui est traditionnellement nommée self
dans la liste des paramètres. (Vous pouvez, en fait, le nommer autre chose, et votre code fonctionnera correctement, mais d'autres codeurs Python vous fronceront les sourcils.)
" self " est l'objet d'instance automatiquement passé à la méthode de l'instance de classe lors de son appel, pour identifier l'instance qui l'a appelée. " self " est utilisé pour accéder à d'autres attributs ou méthodes de l'objet depuis l'intérieur de la méthode. (les méthodes sont essentiellement des fonctions qui appartiennent à une classe)
" self " n'a pas besoin d'être utilisé lors de l'appel d'une méthode alors que vous avez déjà une instance disponible.
Accès à l'attribut "some_attribute" depuis l'intérieur d'une méthode:
class MyClass(object):
some_attribute = "hello"
def some_method(self, some_string):
print self.some_attribute + " " + some_string
Accès à l'attribut "some_attribute" à partir d'une instance existante:
>>> # create the instance
>>> inst = MyClass()
>>>
>>> # accessing the attribute
>>> inst.some_attribute
"hello"
>>>
>>> # calling the instance's method
>>> inst.some_method("world") # In addition to "world", inst is *automatically* passed here as the first argument to "some_method".
hello world
>>>
Voici un petit code pour démontrer que self est identique à l'instance:
>>> class MyClass(object):
>>> def whoami(self, inst):
>>> print self is inst
>>>
>>> local_instance = MyClass()
>>> local_instance.whoami(local_instance)
True
Comme mentionné par d'autres, il est nommé " self " par convention, mais il pourrait être nommé n'importe quoi.
self
fait référence à l'instance actuelle de Bank
. Lorsque vous créez un nouveau Bank
et appelez create_atm
dessus, self
sera implicitement passé par python, et fera référence à la banque que vous avez créée.
Je ne vois pas immédiatement ce que
self
pointe. C'est certainement un symptôme de ne pas comprendre les cours, sur lequel je travaillerai à un moment donné.
self
est un argument passé à la fonction. En Python, ce premier argument est implicitement l'objet sur lequel la méthode a été invoquée. En d'autres termes:
class Bar(object):
def someMethod(self):
return self.field
bar = Bar()
bar.someMethod()
Bar.someMethod(bar)
Ces deux dernières lignes ont un comportement équivalent. (Sauf si bar
fait référence à un objet d'une sous-classe de Bar
- alors someMethod()
peut faire référence à un objet fonction différent.)
Notez que vous pouvez nommer le premier argument "spécial" tout ce que vous voulez - self
n'est qu'une convention pour les méthodes.
Je comprends que
i
pointe vers un élément de la listerange(3)
qui, puisqu'il est dans une fonction, n'est pas global. Mais qu'est-ce queself
"pointe vers"?
Le nom self
n'existe pas dans le contexte de cette fonction. Tenter de l'utiliser déclencherait un NameError
.
Exemple de transcription:
>>> class Bar(object):
... def someMethod(self):
... return self.field
...
>>> bar = Bar()
>>> bar.field = "foo"
>>> bar.someMethod()
'foo'
>>> Bar.someMethod(bar)
'foo'
>>> def fn(i):
... return self
...
>>> fn(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fn
NameError: global name 'self' is not defined
La raison pour laquelle "self" est là (par convention) est que lorsque le runtime Python voit un appel de la forme Object.Method (Param1, Param2), il appelle Method avec des paramètres (Object, Param1 , Param2). Donc, si vous appelez ce premier paramètre "self", tout le monde saura de quoi vous parlez.
La raison pour laquelle vous devez le faire fait l'objet d'une autre question.
En ce qui concerne une métaclasse, c'est quelque chose de rarement utilisé. Vous voudrez peut-être regarder: http://python-history.blogspot.com/2009/04/metaclasses-and-extension-classes-aka.html , l'auteur original et actuel dictateur bienveillant pour Life of Python explique ce que c'est, et comment cela a été. Il a également un article sympa sur certaines utilisations possibles, mais la plupart des gens ne l'utilisent jamais directement du tout.
Le point de vue d'un Rubyist (Ruby est mon premier langage de programmation, donc je m'excuse pour les abstractions simplifiées et potentiellement erronées que je suis sur le point d'utiliser)
pour autant que je sache, l'opérateur point, par exemple:
os.path
est tel que os
est passé dans path()
comme première variable "invisible"
C'est comme si os.path
Était VRAIMENT ceci:
path(os)
S'il y avait une guirlande, j'imagine que ceci:
os.path.filename
Serait un peu comme ça en réalité *:
filename(path(os))
Voici la partie offensive Donc, avec l'auto-variable, tout ce que vous faites est d'autoriser la MÉTHODE DE CLASSE (d'un point de vue rubyiste python 'les méthodes d'instance' semblent être des méthodes de classe). ..) pour agir comme une méthode d'instance en lui faisant passer une instance en tant que première variable (via la méthode point "sneaky" ci-dessus) qui est appelée self
par convention.
c = ClassName()
c.methodname
mais la classe elle-même:
ClassName.methodname
la classe serait transmise plutôt que l'instance.
OK, il est également important de se rappeler que la méthode __init__
Est appelée "magique" par certains. Ne vous inquiétez donc pas de ce qui est passé pour générer une nouvelle instance. Pour être honnête, c'est probablement nil
.
self
fait référence à une instance de la classe.