@hop: Interesujące stwierdzenie, ale nie podałeś żadnego przykładu ani dowodu, że nie jest to duplikat. Dlaczego to mówisz?
S.Lott,
2
@ S.Lott - co? Drugie pytanie dotyczy tego, dlaczego musimy wyraźnie przekazać siebie. Ten pyta o różnicę, ponieważ zmienne klas i instancji.
Dana,
1
@ S.Lott To nie jest to samo pytanie. Nawet spojrzałem na to, zanim o to zapytałem.
ryeguy
2
@ S.Lott: 68282 to bezużyteczne pytanie o to, dlaczego musisz jawnie stawiać siebie jako pierwszy argument metod; to pytanie dotyczy różnicy między członkami klasy i instancji. S.Lott, bardzo podoba mi się twój wkład w SO, ale tym razem się mylisz.
Odpowiedzi:
137
A.xjest zmienną klasową .
Bjest self.xto zmienna przykład .
czyli Ajest xdzielone między wystąpieniami.
Byłoby łatwiej zademonstrować różnicę w czymś, co można zmodyfikować, jak 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)
Może też opublikuj wyjście swojego skryptu, wtedy można zobaczyć różnicę bez kopiowania i samodzielnego uruchamiania ...
Martin
2
Czy w takim razie jaźń Pythona jest odpowiednikiem Javy? Przepraszam za noobizm, proszę
Jean Azzopardi
2
@Jean - Yes-ish - self musi być zwykłą nazwą nadaną pierwszemu parametrowi metod instancji - a python jawnie przekazuje bieżące wystąpienie metod instancji jako pierwszy argument do metod instancji. Ale robi to samo, co Java
Douglas Leeder
@Jean Azzopardi: self jest prawie jak Java (i c ++) this. Jaźń jest po prostu wymagana; czasami jest to rozumiane przez kompilator Java (innym razem jest to wymagane).
S.Lott,
@Douglas Leeder - nie ma problemu.
UnkwnTech
56
Podobnie jak marginesie: selfto właściwie tylko losowo wybrane słowo, które wykorzystuje wszystkich, ale można też użyć this, foolub myselfczy cokolwiek innego chcesz, to tylko pierwszy parametr każdego non statycznej metody dla klasy. Oznacza to, że słowo selfnie jest konstrukcją językową, ale tylko nazwą:
Ax jest zmienną klasy i będzie współdzielona we wszystkich wystąpieniach A, chyba że zostanie wyraźnie nadpisana w ramach wystąpienia. Bx jest zmienną instancji, a każda instancja B ma swoją własną wersję.
Mam nadzieję, że poniższy przykład Pythona może wyjaśnić:
>>> 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.idprint'machine2.id', machine2.idprint'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
Dopiero co zacząłem uczyć się języka Python i przez pewien czas to też mnie zdezorientowało. Próbując dowiedzieć się, jak to wszystko ogólnie działa, wymyśliłem ten bardzo prosty fragment kodu:
# 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()
Kiedy dzwonimy out(), otrzymujemy:
>>> obj.out()
red!
Kiedy dzwonimy out2():
>>> obj.out2()
blue!
Kiedy dzwonimy out3():
>>> obj.out3()
green!
Tak więc w pierwszej metodzie selfokreśla, że Python powinien używać zmiennej (atrybutu), która „należy” do utworzonego przez nas obiektu klasy, a nie globalnego (poza klasą). Więc używa color = "red". W metodzie Python niejawnie podstawia selfnazwę utworzonego przez nas obiektu ( obj). self.coloroznacza „otrzymuję color="red"zobj ”
W drugiej metodzie nie ma selfwskazania obiektu, z którego ma być pobrany kolor, więc dostajemy kolor globalny color = 'blue'.
W trzeciej metodzie zamiast tego selfużyliśmy obj2- nazwa innego obiektu do pobrania color. Dostaje color = 'green'.
Odpowiedzi:
A.x
jest zmienną klasową .B
jestself.x
to zmienna przykład .czyli
A
jestx
dzielone między wystąpieniami.Byłoby łatwiej zademonstrować różnicę w czymś, co można zmodyfikować, jak 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)
Wynik
A's x: [1, 1] B's x: [1]
źródło
Podobnie jak marginesie:
self
to właściwie tylko losowo wybrane słowo, które wykorzystuje wszystkich, ale można też użyćthis
,foo
lubmyself
czy cokolwiek innego chcesz, to tylko pierwszy parametr każdego non statycznej metody dla klasy. Oznacza to, że słowoself
nie jest konstrukcją językową, ale tylko nazwą:>>> class A: ... def __init__(s): ... s.bla = 2 ... >>> >>> a = A() >>> a.bla 2
źródło
Ax jest zmienną klasy i będzie współdzielona we wszystkich wystąpieniach A, chyba że zostanie wyraźnie nadpisana w ramach wystąpienia. Bx jest zmienną instancji, a każda instancja B ma swoją własną wersję.
Mam nadzieję, że poniższy przykład Pythona może wyjaśnić:
>>> 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
źródło
Tłumaczyłem to na tym przykładzie
# 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
Wyjście będzie wtedy
źródło
Dopiero co zacząłem uczyć się języka Python i przez pewien czas to też mnie zdezorientowało. Próbując dowiedzieć się, jak to wszystko ogólnie działa, wymyśliłem ten bardzo prosty fragment kodu:
# 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()
Kiedy dzwonimy
out()
, otrzymujemy:>>> obj.out() red!
Kiedy dzwonimy
out2()
:>>> obj.out2() blue!
Kiedy dzwonimy
out3()
:>>> obj.out3() green!
Tak więc w pierwszej metodzie
self
określa, że Python powinien używać zmiennej (atrybutu), która „należy” do utworzonego przez nas obiektu klasy, a nie globalnego (poza klasą). Więc używacolor = "red"
. W metodzie Python niejawnie podstawiaself
nazwę utworzonego przez nas obiektu (obj
).self.color
oznacza „otrzymujęcolor="red"
zobj
”W drugiej metodzie nie ma
self
wskazania obiektu, z którego ma być pobrany kolor, więc dostajemy kolor globalnycolor = 'blue'
.W trzeciej metodzie zamiast tego
self
użyliśmyobj2
- nazwa innego obiektu do pobraniacolor
. Dostajecolor = 'green'
.źródło