Quel est le but du moi?

Quel est le but du mot self en Python? Je comprends qu'il se réfère à l'objet spécifique créé à partir de cette classe, mais je ne vois pas pourquoi il explicitement doit être ajouté à chaque fonction en tant que paramètre. Pour illustrer, dans Ruby je peux faire ceci:

class myClass
    def myFunc(name)
        @name = name
    end
end

que je comprends très bien. Cependant en Python je dois inclure self :

class myClass:
    def myFunc(self, name):
        self.name = name

quelqu'un peut-il m'en parler? Ce n'est pas quelque chose que je suis venu dans mon (certes limitée) de l'expérience.

907
demandé sur kmario23 2010-04-26 00:22:28
la source

19 ответов

la raison pour laquelle vous devez utiliser self. est que Python n'utilise pas la syntaxe @ pour se référer aux attributs des instances. Python a décidé de faire, des méthodes d'une manière qui rend l'instance à laquelle la méthode est être passé automatiquement, mais pas reçu automatiquement: le premier paramètre de méthodes est l'exemple, la méthode est appelée. Cela rend les méthodes entièrement les mêmes que les fonctions, et laisse le nom réel à utilisez jusqu'à vous (bien que self soit la convention, et les gens seront généralement froncer les sourcils lorsque vous utilisez autre chose.) self n'est pas spécial pour le code, c'est juste un autre objet.

Python aurait pu faire autre chose pour distinguer les noms normaux des attributs -- une syntaxe spéciale comme Ruby a, ou exiger des déclarations comme C++ et Java do, ou peut-être quelque chose de plus différent -- mais ce n'est pas le cas. Python est tout pour rendre les choses explicites, le faire ce qui est évident, et bien qu'il ne le fasse pas entièrement partout, il le fait par exemple attributs. C'est pourquoi assigner à un attribut d'instance doit savoir à quelle instance attribuer, et c'est pourquoi il a besoin de self. .

600
répondu Thomas Wouters 2010-04-28 03:01:28
la source

prenons une classe de vecteur simple:

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

Nous voulons avoir une méthode qui calcule la longueur. A quoi ressemblerait-il si on voulait le définir dans la classe?

    def length(self):
        return math.sqrt(self.x ** 2 + self.y ** 2)

à quoi devrait-elle ressembler lorsque nous la définirons comme une méthode/fonction globale?

def length_global(vector):
    return math.sqrt(vector.x ** 2 + vector.y ** 2)

donc toute la structure reste la même. Comment me faire de l'utilisation de ce? Si nous supposons un instant que nous n'avions pas ecrit une méthode length pour notre classe Vector , nous pourrions faire ceci:

Vector.length_new = length_global
v = Vector(3, 4)
print(v.length_new()) # 5.0

cela fonctionne parce que le premier paramètre de length_global , peut être réutilisé comme le paramètre self dans length_new . Cela ne serait pas possible sans un self explicite .


une autre façon de comprendre la nécessité de l'explicite self est de voir où Python ajoute du sucre syntaxique. Lorsque vous garder dans l'esprit, que, fondamentalement, un appel comme

v_instance.length()

est transformé en

Vector.length(v_instance)

il est facile de voir où se situe le self . Vous n'écrivez pas réellement les méthodes d'instance en Python; ce que vous écrivez est les méthodes de classe qui doivent prendre une instance comme premier paramètre. Et par conséquent, vous devrez placer le paramètre instance quelque part explicitement.

386
répondu Debilski 2017-08-15 09:40:38
la source

disons que vous avez une classe ClassA qui contient une méthode methodA définie comme:

def methodA(self, arg1, arg2):
    # do something

et ObjectA sont des exemples de cette classe.

maintenant quand ObjectA.methodA(arg1, arg2) est appelé, python le convertit en interne comme:

ClassA.methodA(ObjectA, arg1, arg2)

la variable self renvoie à l'objet lui-même.

292
répondu Arjun Sreedharan 2015-01-18 19:10:51
la source

Lorsque les objets sont instanciés, l'objet lui-même est passé dans le paramètre.

enter image description here

pour cette Raison, les données de l'objet est lié à l'objet. Ci-dessous est un exemple de la façon dont vous pourriez vouloir visualiser ce que les données de chaque objet pourrait regarder. Notez comment 'self' est remplacé par le nom de l'objet. Je ne dis pas que ce diagramme d'exemple ci-dessous est tout à fait exact, mais il faut espérer avec servir un but dans la visualisation l'utilisation de l'auto.

enter image description here

l'objet est passé dans le paramètre self de sorte que l'objet puisse garder ses propres données.

bien que cela ne soit pas tout à fait exact, pensez au processus d'instanciation d'un objet comme celui-ci: Lorsqu'un objet est créé, il utilise la classe comme un modèle pour ses propres données et méthodes. Sans passer son propre nom dans le paramètre, les attributs et les méthodes de la classe restera comme un modèle général et ne serait pas référencé d' (appartenir) de l'objet. Ainsi, en passant le nom de l'objet dans le paramètre self, cela signifie que si 100 objets sont instanciés à partir d'une seule classe, ils peuvent tous garder une trace de leurs propres données et méthodes.

voir l'illustration ci-dessous:

enter image description here

157
répondu sw123456 2015-06-28 08:47:02
la source

j'aime cet exemple:

class A: 
    foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: [5]

class A: 
    def __init__(self): 
        self.foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: []
65
répondu kame 2010-04-26 20:02:48
la source

je vais démontrer par un code que n'utilise pas les classes :

def state_init(state):
    state['field'] = 'init'

def state_add(state, x):
    state['field'] += x

def state_mult(state, x):
    state['field'] *= x

def state_getField(state):
    return state['field']

myself = {}
state_init(myself)
state_add(myself, 'added')
state_mult(myself, 2)

print( state_getField(myself) )
#--> 'initaddedinitadded'
Les Classes

sont juste un moyen d'éviter de passer tout le temps dans cette chose" d'état " (et d'autres bonnes choses comme l'initialisation, la composition de classe, les métaclasses rarement nécessaires, et le soutien des méthodes personnalisées pour outrepasser les opérateurs).

maintenant, nous allons démontrer le code ci-dessus en utilisant la machine intégrée de la classe python, pour montrer comment il est fondamentalement le même chose.

class State(object):
    def __init__(self):
        self.field = 'init'
    def add(self, x):
        self.field += x
    def mult(self, x):
        self.field *= x

s = State()
s.add('added')    # self is implicitly passed in
s.mult(2)         # self is implicitly passed in
print( s.field )

[migré ma réponse de dupliquer une question fermée]

33
répondu ninjagecko 2011-06-22 04:27:23
la source

ainsi que toutes les autres raisons déjà indiquées, il permet un accès plus facile aux méthodes dépassées; vous pouvez appeler Class.some_method(inst) .

exemple d'utilité:

class C1(object):
    def __init__(self):
         print "C1 init"

class C2(C1):
    def __init__(self): #overrides C1.__init__
        print "C2 init"
        C1.__init__(self) #but we still want C1 to init the class too
>>> C2()
"C2 init"
"C1 init"
17
répondu Ponkadoodle 2013-12-25 02:23:49
la source

les extraits suivants sont tirés de la documentation Python sur self :

comme dans Modula-3, Il n'y a pas de raccourcis [en Python] pour référencer les membres de l'objet à partir de ses méthodes: la fonction de méthode est déclarée avec un premier argument explicite représentant l'objet, qui est fourni implicitement par l'appel.

souvent, le premier argument d'une méthode est appelé soi. Ce n'est rien de plus qu'une convention: le nom self n'a absolument aucune signification particulière pour Python. Notez, cependant, qu'en ne Suivant pas la convention votre code peut être moins lisible par d'autres programmeurs Python, et il est également concevable qu'un programme de navigateur de classe puisse être écrit qui repose sur une telle convention.

pour plus d'informations, consultez le tutoriel de documentation Python sur les classes .

16
répondu Matthew Rankin 2010-04-26 18:09:29
la source

Python n'est pas un langage conçu pour la programmation orientée objet contrairement à Java ou C++.

quand on appelle une méthode statique en Python, on écrit simplement une méthode avec des arguments réguliers à l'intérieur.

class Animal():
    def staticMethod():
        print "This is a static method"

cependant, une méthode objet, qui vous demande de faire une variable, qui est un Animal, dans ce cas, a besoin de l'auto-argument

class Animal():
    def objectMethod(self):
        print "This is an object method which needs an instance of a class"

la méthode self est également utilisée pour se référer à un champ variable au sein de la classe.

class Animal():
    #animalName made in constructor
    def Animal(self):
        self.animalName = "";


    def getAnimalName(self):
        return self.animalName

dans ce cas, self se réfère à la variable animalName de toute la classe. Rappelez-vous: si vous avez une variable dans une méthode, self ne fonctionnera pas. Cette variable n'existe que lorsque la méthode est en cours d'exécution. Pour définir les champs (les variables de la classe entière), vous devez les définir en dehors des méthodes de classe.

si vous ne comprenez pas un seul mot de ce que je dis, puis Google " objet Programmation Orientée."Une fois que vous comprenez cela, vous n'aurez même pas besoin de poser cette question :).

11
répondu ytpillai 2017-09-21 21:39:06
la source

Son utilisation est similaire à l'utilisation de this clé en Java, c'est à dire à donner une référence à l'objet courant.

10
répondu Gaurav Nishant 2017-02-27 12:47:48
la source

il est là pour suivre le zen de Python"explicite est mieux qu'implicite". C'est en effet une référence à votre classe d'objet. En Java et PHP, par exemple, il est appelé this .

si user_type_name est un champ sur votre modèle, vous y accédez par self.user_type_name .

7
répondu dan-klasson 2013-12-25 02:24:58
la source

self est une référence à l'objet lui-même, par conséquent, ils sont identiques. Les méthodes Python ne sont pas appelées dans le contexte de l'objet lui-même. self en Python peut être utilisé pour traiter des modèles d'objets personnalisés ou quelque chose.

4
répondu Ming-Tang 2010-04-26 00:26:35
la source

je suis surpris que personne n'ait parlé de Lua. Lua utilise également la variable "self", mais elle peut être omise mais utilisée. C++ fait la même chose avec 'ceci'. Je ne vois aucune raison d'avoir à déclarer "self" dans chaque fonction mais vous devriez quand même pouvoir l'utiliser comme vous le pouvez avec lua et C++. Pour un langage qui s'enorgueillit d'être bref, il est étrange qu'il exige que vous déclariez l'auto-variable.

3
répondu user441521 2016-01-12 21:10:32
la source

est parce que par la façon dont python est conçu les alternatives ne fonctionneraient guère. Python est conçu pour permettre de définir des méthodes ou des fonctions dans un contexte où à la fois implicite this (A-La Java/C++) ou explicite @ (a-la ruby) ne fonctionnerait pas. Prenons un exemple avec l'approche explicite avec les conventions python:

def fubar(x):
    self.x = x

class C:
    frob = fubar

maintenant la fonction fubar ne fonctionnerait pas puisqu'elle supposerait que self est une variable globale (et dans frob ). L'alternative serait d'exécuter des méthodes avec une portée globale remplacée (où self est l'objet).

L'implicite approche serait

def fubar(x)
    myX = x

class C:
    frob = fubar

Cela signifierait que myX pourrait être interprété comme une variable locale dans fubar (et frob ). L'alternative ici serait d'exécuter des méthodes avec une portée locale remplacée qui est conservée entre les appels, mais qui supprimer la posibilité des variables locales de la méthode.

cependant la situation actuelle fonctionne bien:

 def fubar(self, x)
     self.x = x

 class C:
     frob = fubar

ici, lorsqu'il est appelé comme méthode frob recevra l'objet sur lequel il est appelé via le paramètre self , et fubar peut encore être appelé avec un objet comme paramètre et travailler le même (il est le même que C.frob je pense).

2
répondu skyking 2015-08-27 10:31:02
la source

tout d'abord, self est un nom conventionnel, vous pourriez mettre n'importe quoi d'autre (étant cohérent) à sa place.

il se réfère à l'objet lui-même, donc quand vous l'utilisez, vous le déclarez .nom et .l'âge est une propriété des objets de L'élève (note, Pas de la classe de L'élève) que vous allez créer.

class Student:
    #called each time you create a new Student instance
    def __init__(self,name,age): #special method to initialize
        self.name=name
        self.age=age

    def __str__(self): #special method called for example when you use print
        return "Student %s is %s years old" %(self.name,self.age)

    def call(self, msg): #silly example for custom method
        return ("Hey, %s! "+msg) %self.name

#initializing two instances of the student class
bob=Student("Bob",20)
alice=Student("Alice",19)

#using them
print bob.name
print bob.age
print alice #this one only works if you define the __str__ method
print alice.call("Come here!") #notice you don't put a value for self

#you can modify attributes, like when alice ages
alice.age=20
print alice

Code ici

2
répondu harrypotter0 2018-01-12 07:45:25
la source

dans la méthode __init__ , self se réfère à l'objet nouvellement créé; dans d'autres méthodes de classe, il se réfère à l'instance dont la méthode a été appelée.

moi, comme un nom , est juste une convention , appelez-le comme vous voulez ! mais lors de son utilisation, par exemple pour supprimer l'objet, vous devez utiliser le même nom: __del__(var) , où var a été utilisé dans le __init__(var,[...])

vous devez prendre un regardez cls aussi, pour avoir la vue d'ensemble . Ce post pourrait être utile.

1
répondu TheEnglishMe 2017-05-23 15:18:30
la source

regardez l'exemple suivant, qui explique clairement le but de self

class Restaurant(object):  
    bankrupt = False

    def open_branch(self):
        if not self.bankrupt:
           print("branch opened")

#create instance1
>>> x = Restaurant()
>>> x.bankrupt
False

#create instance2
>>> y = Restaurant()
>>> y.bankrupt = True   
>>> y.bankrupt
True

>>> x.bankrupt
False  

self est utilisé/nécessaire de faire la distinction entre les instances.

1
répondu kmario23 2014-11-15 10:54:27
la source

L'utilisation de l'argument, traditionnellement appelées self n'est pas aussi difficile à comprendre, comme c'est pourquoi est-il nécessaire? Ou pourquoi le mentionner explicitement? Cela, je suppose, est une plus grande question pour la plupart des utilisateurs qui cherchent cette question, ou si ce n'est pas le cas, ils auront certainement la même question pendant qu'ils avancent en apprenant python. Je leur recommande de lire ces deux blogs:

1: Utilisation de soi expliqué

Notez qu'il n'est pas un mot-clé.

le premier argument de chaque méthode de classe, y compris init, est toujours une référence à l'instance courante de la classe. Par convention, cet argument est toujours appelé self. Dans la méthode init, self se réfère à l'objet nouvellement créé; dans d'autres méthodes de classe, il se réfère à l'instance dont la méthode a été appelée. Par exemple, le code ci-dessous est le même que le code ci-dessus.

2: Pourquoi l'avons-nous de cette façon et pourquoi ne pouvons-nous pas l'éliminer comme un argument, comme Java, et avoir un mot-clé à la place

une autre chose que je voudrais ajouter est, un argument optionnel self me permet de déclarer des méthodes statiques à l'intérieur d'une classe, en n'écrivant pas self .

exemples de Code:

class MyClass():
    def staticMethod():
        print "This is a static method"

    def objectMethod(self):
        print "This is an object method which needs an instance of a class, and that is what self refers to"

PS : cela ne fonctionne qu'en Python 3.x.

en précédent versions, vous devez ajouter explicitement @staticmethod decorator, sinon self argument est obligatoire.

1
répondu Bugs Buggy 2018-08-12 13:20:06
la source

c'est une référence explicite à l'objet de l'instance de classe.

-2
répondu SilentGhost 2010-04-26 00:24:57
la source

Autres questions sur python class oop self