Czym różnią się te dwie klasy?
class A():
x=3
class B():
def __init__(self):
self.x=3
Czy jest jakaś znacząca różnica?
Czym różnią się te dwie klasy?
class A():
x=3
class B():
def __init__(self):
self.x=3
Czy jest jakaś znacząca różnica?
Odpowiedzi:
A.x
jest zmienną klasową .
B
jest self.x
to zmienna przykład .
czyli A
jest x
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]
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
lub myself
czy cokolwiek innego chcesz, to tylko pierwszy parametr każdego non statycznej metody dla klasy. Oznacza to, że słowo self
nie jest konstrukcją językową, ale tylko nazwą:
>>> class A:
... def __init__(s):
... s.bla = 2
...
>>>
>>> a = A()
>>> a.bla
2
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
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
machine1.id 1 machine2.id 2 machine3.id 3 maszyna 1. licznik 3 maszyna 2. licznik 3 machine3.counter 3
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żywa color = "red"
. W metodzie Python niejawnie podstawia self
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 globalny color = 'blue'
.
W trzeciej metodzie zamiast tego self
użyliśmy obj2
- nazwa innego obiektu do pobrania color
. Dostaje color = 'green'
.