@hop: afirmación interesante, pero no ha proporcionado ningún ejemplo o evidencia de que no sea un duplicado. ¿Por qué dices eso?
S.Lott
2
@ S.Lott - ¿Eh? La otra pregunta es por qué necesitamos pasarnos explícitamente a nosotros mismos. Este pregunta sobre la diferencia debido a las variables de clase e instancia.
Dana
1
@ S.Lott Esa no es la misma pregunta. Incluso miré ese antes de preguntarlo.
ryeguy
2
@ S.Lott: 68282 es una pregunta inútil sobre por qué tienes que poner explícitamente self como el primer argumento de los métodos; esta pregunta se refiere a la diferencia entre miembros de clase e instancia. S. Lot, me gustan mucho tus contribuciones a SO, pero esta vez te equivocas.
Respuestas:
137
A.xes una variable de clase .
B's self.xes una variable de instancia .
es decir, A's xes compartida entre instancias.
Sería más fácil demostrar la diferencia con algo que se pueda modificar como una lista:
#!/usr/bin/env pythonclassA:
x = []
defadd(self):
self.x.append(1)
classB:def__init__(self):
self.x = []
defadd(self):
self.x.append(1)
x = A()
y = A()
x.add()
y.add()
print("A's x:", x.x)
x = B()
y = B()
x.add()
y.add()
print("B's x:", x.x)
Tal vez también publique la salida de su script, entonces uno puede ver la diferencia sin copiarlo y ejecutarlo uno mismo ...
Martin
7
Agregué la salida.
UnkwnTech
2
Entonces, ¿es el yo de Python equivalente al de Java? Disculpe la novicia por favor
Jean Azzopardi
2
@Jean - Yes-ish - self tiene que ser solo el nombre convencional dado al primer parámetro de los métodos de instancia - y Python pasa explícitamente la instancia actual de los métodos de instancia como el primer argumento a los métodos de instancia. Pero hace el mismo trabajo que el de Java
Douglas Leeder
@Jean Azzopardi: self es casi como Java (y c ++) esto. El yo es simplemente necesario; esto a veces es razonado por el compilador de Java (otras veces es necesario)
S.Lott
56
Así como una nota al margen: selfen realidad es sólo una palabra elegido al azar, que todo el mundo utiliza, pero también se puede utilizar this, fooo myself, o cualquier otra cosa que desee, es sólo el primer parámetro de cada método no estático para una clase. Esto significa que la palabra selfno es una construcción del lenguaje, sino solo un nombre:
Ax es una variable de clase y se compartirá en todas las instancias de A, a menos que se anule específicamente dentro de una instancia. Bx es una variable de instancia y cada instancia de B tiene su propia versión.
Espero que el siguiente ejemplo de Python pueda aclarar:
>>> classFoo():
... i = 3
... defbar(self):
... print'Foo.i is', Foo.i
... print'self.i is', self.i
...
>>> f = Foo() # Create an instance of the Foo class
>>> f.bar()
Foo.i is3
self.i is3
>>> Foo.i = 5# Change the global value of Foo.i over all instances
>>> f.bar()
Foo.i is5
self.i is5
>>> f.i = 3# Override this instance's definition of i
>>> f.bar()
Foo.i is5
self.i is3
# By TMOTTMclassMachine:# Class Variable counts how many machines have been created.# The value is the same for all objects of this class.
counter = 0def__init__(self):# Notice: no 'self'.
Machine.counter += 1# Instance variable.# Different for every object of the class.
self.id = Machine.counter
if __name__ == '__main__':
machine1 = Machine()
machine2 = Machine()
machine3 = Machine()
#The value is different for all objects.print'machine1.id', machine1.id
print'machine2.id', machine2.id
print'machine3.id', machine3.id
#The value is the same for all objects.print'machine1.counter', machine1.counter
print'machine2.counter', machine2.counter
print'machine3.counter', machine3.counter
Acabo de comenzar a aprender Python y esto también me confundió durante algún tiempo. Tratando de averiguar cómo funciona todo en general, se me ocurrió este código muy simple:
# Create a class with a variable inside and an instance of that classclassOne:
color = 'green'
obj2 = One()
# Here we create a global variable(outside a class suite).
color = 'blue'# Create a second class and a local variable inside this class. classTwo:
color = "red"# Define 3 methods. The only difference between them is the "color" part.defout(self):
print(self.color + '!')
defout2(self):
print(color + '!')
defout3(self):
print(obj2.color + '!')
# Create an object of the class One
obj = Two()
Cuando llamamos out()obtenemos:
>>> obj.out()
red!
Cuando llamamos out2():
>>> obj.out2()
blue!
Cuando llamamos out3():
>>> obj.out3()
green!
Entonces, en el primer método se selfespecifica que Python debe usar la variable (atributo), que "pertenece" al objeto de la clase que creamos, no a uno global (fuera de la clase). Entonces usa color = "red". En el método, Python sustituye implícitamente selfel nombre de un objeto que creamos ( obj). self.colorsignifica "estoy obteniendo color="red"del obj"
En el segundo método no hay selfque especificar el objeto de donde se debe tomar el color, por lo que obtiene el global color = 'blue'.
En el tercer método, en lugar del selfque usamos obj2, un nombre de otro objeto del que obtener color. Se pone color = 'green'.
Respuestas:
A.x
es una variable de clase .B
'sself.x
es una variable de instancia .es decir,
A
'sx
es compartida entre instancias.Sería más fácil demostrar la diferencia con algo que se pueda modificar como una lista:
#!/usr/bin/env python class A: x = [] def add(self): self.x.append(1) class B: def __init__(self): self.x = [] def add(self): self.x.append(1) x = A() y = A() x.add() y.add() print("A's x:", x.x) x = B() y = B() x.add() y.add() print("B's x:", x.x)
Salida
A's x: [1, 1] B's x: [1]
fuente
Así como una nota al margen:
self
en realidad es sólo una palabra elegido al azar, que todo el mundo utiliza, pero también se puede utilizarthis
,foo
omyself
, o cualquier otra cosa que desee, es sólo el primer parámetro de cada método no estático para una clase. Esto significa que la palabraself
no es una construcción del lenguaje, sino solo un nombre:>>> class A: ... def __init__(s): ... s.bla = 2 ... >>> >>> a = A() >>> a.bla 2
fuente
Ax es una variable de clase y se compartirá en todas las instancias de A, a menos que se anule específicamente dentro de una instancia. Bx es una variable de instancia y cada instancia de B tiene su propia versión.
Espero que el siguiente ejemplo de Python pueda aclarar:
>>> class Foo(): ... i = 3 ... def bar(self): ... print 'Foo.i is', Foo.i ... print 'self.i is', self.i ... >>> f = Foo() # Create an instance of the Foo class >>> f.bar() Foo.i is 3 self.i is 3 >>> Foo.i = 5 # Change the global value of Foo.i over all instances >>> f.bar() Foo.i is 5 self.i is 5 >>> f.i = 3 # Override this instance's definition of i >>> f.bar() Foo.i is 5 self.i is 3
fuente
Solía explicarlo con este ejemplo
# By TMOTTM class Machine: # Class Variable counts how many machines have been created. # The value is the same for all objects of this class. counter = 0 def __init__(self): # Notice: no 'self'. Machine.counter += 1 # Instance variable. # Different for every object of the class. self.id = Machine.counter if __name__ == '__main__': machine1 = Machine() machine2 = Machine() machine3 = Machine() #The value is different for all objects. print 'machine1.id', machine1.id print 'machine2.id', machine2.id print 'machine3.id', machine3.id #The value is the same for all objects. print 'machine1.counter', machine1.counter print 'machine2.counter', machine2.counter print 'machine3.counter', machine3.counter
La salida entonces será
fuente
Acabo de comenzar a aprender Python y esto también me confundió durante algún tiempo. Tratando de averiguar cómo funciona todo en general, se me ocurrió este código muy simple:
# Create a class with a variable inside and an instance of that class class One: color = 'green' obj2 = One() # Here we create a global variable(outside a class suite). color = 'blue' # Create a second class and a local variable inside this class. class Two: color = "red" # Define 3 methods. The only difference between them is the "color" part. def out(self): print(self.color + '!') def out2(self): print(color + '!') def out3(self): print(obj2.color + '!') # Create an object of the class One obj = Two()
Cuando llamamos
out()
obtenemos:>>> obj.out() red!
Cuando llamamos
out2()
:>>> obj.out2() blue!
Cuando llamamos
out3()
:>>> obj.out3() green!
Entonces, en el primer método se
self
especifica que Python debe usar la variable (atributo), que "pertenece" al objeto de la clase que creamos, no a uno global (fuera de la clase). Entonces usacolor = "red"
. En el método, Python sustituye implícitamenteself
el nombre de un objeto que creamos (obj
).self.color
significa "estoy obteniendocolor="red"
delobj
"En el segundo método no hay
self
que especificar el objeto de donde se debe tomar el color, por lo que obtiene el globalcolor = 'blue'
.En el tercer método, en lugar del
self
que usamosobj2
, un nombre de otro objeto del que obtenercolor
. Se ponecolor = 'green'
.fuente