1221 votes

Python ' soi ' a expliqué

Quel est le but de l' self mot 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, en Ruby, je peux faire ceci:

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

Ce que je comprends, assez facilement. Cependant en Python j'ai besoin d'inclure self:

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

Quelqu'un peut-il me parler à travers cela? Il n'est pas quelque chose que j'ai trouver dans mon (certes limitée) de l'expérience.

744voto

Thomas Wouters Points 38811

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

Python aurait pu faire quelque chose d'autre à distinguer normale noms d'attributs -- syntaxe particulière comme le Rubis a, ou d'exiger des déclarations comme C++ et Java, ou peut-être quelque chose de plus différent, mais il n'a pas. Python est tout pour rendre les choses explicite, de le rendre vivant ce qu'il en est, et bien qu'il ne le fait pas entièrement partout, il le fait faire par exemple des attributs. C'est pourquoi l'attribution à une instance de l'attribut a besoin de savoir quelle instance à attribuer, et c'est pourquoi il a besoin d' self..

509voto

Arjun Sreedharan Points 1387

Imaginons que vous ayez une classe qui contient une méthode définie comme :

et `` est une instance de cette classe.

Maintenant lorsque `` est appelé, python en interne le convertit pour vous en tant que :

``

La `` la variable fait référence à l’objet lui-même.

432voto

Debilski Points 28586

J'ai été confondu par ce aussi bien pour un bon moment et je ne crois pas que la raison pour laquelle cela a eu beaucoup à faire avec la souvent prononcé explicite est mieux qu'implicite , mais que c'est seulement à la suite d'une simple analogie.

Prenons un simple vecteur de la classe:

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

Maintenant, nous voulons avoir une méthode qui calcule la longueur. Que se passerait-il si nous voulions définir à l'intérieur de la classe?

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

Et, ce qui devrait ressembler lorsque nous étions à la définir comme une méthode globale/fonction?

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

Ainsi, l'ensemble de la structure reste la même. Maintenant, comment pouvons-moi de rendre l'utilisation de ce? Si nous supposons pour un moment que nous n'avions pas écrit une length méthode pour notre Vector classe, on peut 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 l' length_global, peut être ré-utilisé comme self paramètre en length_new. Ce ne serait pas possible sans une explicite self.


Une autre manière de comprendre la nécessité pour l'explicite self est de voir où Python ajoute du sucre syntaxique. Lorsque vous gardez à l'esprit, que, fondamentalement, un appel comme

v_instance.length()

est transformée en interne

Vector.length(v_instance)

il est facile de voir où l' self correspond. Vous ne vous sentez pas à l'écriture de méthodes d'instance en Python, ce que vous écrivez est les méthodes de la classe qui (doit) avoir une instance en tant que premier paramètre. Et donc, vous aurez à placer l'instance paramètre quelque part de manière explicite.

84voto

kame Points 1779

J’aime cet exemple :

44voto

ninjagecko Points 25709

Je vais le démontrer avec un code qui n'utilise pas de 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 ne sont qu'un moyen d'éviter de passer dans cet "état de chose" de tous les temps (et d'autres choses agréables, comme lors de l'initialisation, la composition de classe, la rarement nécessaire metaclasses, et le soutien à des méthodes personnalisées pour remplacer les opérateurs).

Maintenant, nous allons démontrer le code ci-dessus en utilisant le haut-python classe de machines, de montrer comment il est fondamentalement la 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]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X