Wie unterscheiden sich diese beiden Klassen?
class A():
x=3
class B():
def __init__(self):
self.x=3
Gibt es einen signifikanten Unterschied?
Wie unterscheiden sich diese beiden Klassen?
class A():
x=3
class B():
def __init__(self):
self.x=3
Gibt es einen signifikanten Unterschied?
Antworten:
A.x
ist eine Klassenvariable .
B
's self.x
ist eine Instanzvariable .
dh A
's x
wird zwischen Instanzen geteilt.
Es wäre einfacher, den Unterschied mit etwas zu demonstrieren, das wie eine Liste geändert werden kann:
#!/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)
Ausgabe
A's x: [1, 1]
B's x: [1]
Nur als Randnotiz: self
Ist eigentlich nur ein zufällig ausgewähltes Wort, das jeder verwendet, aber Sie können es auch verwenden this
, foo
oder myself
oder irgendetwas anderes, das Sie wollen, es ist nur der erste Parameter jeder nicht statischen Methode für eine Klasse. Dies bedeutet, dass das Wort self
kein Sprachkonstrukt ist, sondern nur ein Name:
>>> class A:
... def __init__(s):
... s.bla = 2
...
>>>
>>> a = A()
>>> a.bla
2
Ax ist eine Klassenvariable und wird für alle Instanzen von A gemeinsam genutzt, sofern dies nicht innerhalb einer Instanz ausdrücklich überschrieben wird. Bx ist eine Instanzvariable, und jede Instanz von B hat eine eigene Version davon.
Ich hoffe, das folgende Python-Beispiel kann dies verdeutlichen:
>>> 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
Ich habe es mit diesem Beispiel erklärt
# 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
Die Ausgabe erfolgt dann durch
machine1.id 1 machine2.id 2 machine3.id 3 machine1.counter 3 machine2.counter 3 machine3.counter 3
Ich habe gerade angefangen, Python zu lernen, und das hat mich auch einige Zeit verwirrt. Um herauszufinden, wie das alles im Allgemeinen funktioniert, habe ich mir diesen sehr einfachen Code ausgedacht:
# 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()
Wenn wir anrufen out()
, bekommen wir:
>>> obj.out()
red!
Wenn wir anrufen out2()
:
>>> obj.out2()
blue!
Wenn wir anrufen out3()
:
>>> obj.out3()
green!
In der ersten Methode wird also self
angegeben, dass Python die Variable (Attribut) verwenden soll, die zu dem von uns erstellten Klassenobjekt "gehört", nicht zu einem globalen (außerhalb der Klasse). Also nutzt es color = "red"
. In der Methode ersetzt Python implizit self
den Namen eines von uns erstellten Objekts ( obj
). self.color
bedeutet "Ich komme color="red"
von der obj
"
Bei der zweiten Methode muss self
das Objekt, von dem die Farbe übernommen werden soll, nicht angegeben werden, sodass das globale Objekt erhalten wird color = 'blue'
.
Bei der dritten Methode haben self
wir stattdessen obj2
einen Namen eines anderen Objekts verwendet, von dem wir abrufen möchten color
. Es wird color = 'green'
.