2014-04-25 9 views
29

ich Python ziemlich neu bin, und bemerkte, diese Beiträge: Python __init__ and self what do they do? und Python Classes without using def __init__(self)Nützlichkeit von def __init __ (selbst)?

Nachdem sie mit ihm herumspielen, bemerkte ich jedoch, dass diese beiden Klassen scheinbar ergebnis-

class A(object): 
    def __init__(self): 
     self.x = 'Hello' 

    def method_a(self, foo): 
     print self.x + ' ' + foo 

Äquivalent geben (von this question)

und

class B(object): 
    x = 'Hello' 
    def method_b(self,foo): 
     print self.x + ' ' + foo 

Gibt es einen wirklichen Unterschied zwischen diesen beiden? Oder, ganz allgemein, ändert sich __init__ irgendetwas inhärent über die Attribute einer Klasse? In the documentation wird erwähnt, dass __init__ aufgerufen wird, wenn die Instanz erstellt wird. Bedeutet dies, dass x in Klasse B vor der Instanziierung festgelegt wird?

Antwort

32

Ja, check this out:

class A(object): 
    def __init__(self): 
     self.lst = [] 

class B(object): 
    lst = [] 

und jetzt versuchen:

>>> x = B() 
>>> y = B() 
>>> x.lst.append(1) 
>>> y.lst.append(2) 
>>> x.lst 
[1, 2] 
>>> x.lst is y.lst 
True 

und diese:

>>> x = A() 
>>> y = A() 
>>> x.lst.append(1) 
>>> y.lst.append(2) 
>>> x.lst 
[1] 
>>> x.lst is y.lst 
False 

Bedeutet dies, dass x in der Klasse B hergestellt wird vor der Instantiierung?

Ja, es ist ein Klassenattribut (es wird zwischen Instanzen geteilt). Während in Klasse A ist es ein Instanzattribut. Es passiert einfach, dass Strings unveränderbar sind, daher gibt es in Ihrem Szenario keinen wirklichen Unterschied (außer dass Klasse B weniger Speicher benötigt, weil sie nur einen String für alle Instanzen definiert). Aber in meinem Beispiel gibt es einen riesigen.

+2

+1 Vergessen Sie nicht, dass da Klassen Objekte können Sie das Attribut der Klasse jederzeit selbst ändern. 'Klasse A: bestanden; A.lst = Liste (Bereich (6))'. – kojiro

9

Im ersten Beispiel haben Sie die Variable der Instanz der Klasse. Diese Variable ist nur über eine Instanz zugänglich (selbst erforderlich).

class A(): 
    def __init__(self): 
     self.x = 'hello' 

print A.x -> AttributeError 
print A().x -> 'hello' 

Im zweiten Beispiel haben Sie eine statische Variable. Sie können der Klasse auf den Namen dieser Variablen durch Zugriff auf A

class A(): 
    x = 'hello' 

print A.x -> 'hello' 
print A().x -> 'hello' 

In der Tat Sie eine statische Variable und eine Instanzvariable mit dem gleichen Namen haben:

class A(): 
    x = 'hello' 
    def __init__(self): 
     self.x = 'world' 

print A.x -> hello 
print A().x -> world 

Der statische Wert geteilt wird zwischen allen Instanzen

class A(): 
    x = 'hello' 

    @staticmethod 
    def talk(): 
     print A.x 

a = A() 
print a.talk() -> hello 

A.x = 'world' 
print a.talk() -> world 

Sie haben einen guten Artikel hier: http://linuxwell.com/2011/07/21/static-variables-and-methods-in-python/

4

Wie andere gesagt haben, ist dies der Unterschied zwischen einer Variablen in einer Klasse und einer Variablen in einer Klasse Instanz. Siehe das folgende Beispiel.

>>> class A: 
...  a = [] 
... 
>>> class B: 
...  def __init__(self): 
...   self.b = [] 
... 
>>> a1 = A() 
>>> a1.a.append('hello') 
>>> a2 = A() 
>>> a2.a 
['hello'] 
>>> b1 = B() 
>>> b1.b.append('goodbye') 
>>> b2 = B() 
>>> b2.b 
[] 

Für unveränderliche Objekte wie Tupel, Strings, usw. es schwieriger ist, den Unterschied zu bemerken, aber für mutables, ändert es alles — die vorgenommenen Änderungen zwischen allen Instanzen dieser Klasse geteilt werden.

Beachten Sie auch, dass das gleiche Verhalten für Schlüsselwort-Argument-Standardwerte auftritt!

>>> class A: 
...  def __init__(self, a=[]): 
...   a.append('hello') 
...   print(a) 
... 
>>> A() 
['hello'] 
>>> A() 
['hello', 'hello'] 
>>> A() 
['hello', 'hello', 'hello'] 

>>> class B: 
...  def __init__(self, b=None): 
...   if b is None: 
...    b = [] 
...   b.append('goodbye') 
...   print(b) 
... 
>>> B() 
['goodbye'] 
>>> B() 
['goodbye'] 
>>> B() 
['goodbye'] 

Dieses Verhalten beißt viele neue Python-Programmierer. Gut für Sie, diese Unterschiede frühzeitig zu entdecken!

0

Sie verwenden init Sie müssen nicht verwenden es in Ihrem Fall können Sie nur

enter code here 

class some(): 
    def main(self): 
     self.x=10 
    def mathod_a(self,foo): 
     print self.x+foo' 

und wenn Sie verwenden möchten init versuchen es

enter code here 
class some(): 
def main(self): 
    print(x) 
def init(self,x): 
    self.x=x 
    main() 
Verwandte Themen