2013-07-09 26 views
5

Programlama konusunda çok yeni ve python öğrenmeye başladım. Çok aptalca bir soru olabilir, bu yüzden lütfen cehaletimi affedin. aşağıdaki kod parçasını inceleyin:Python sınıf özniteliklerini anlama

ben kapsamında akıllıca onlar kıyasla tüm yerlerde eşit erişilebilir olarak (onları tanımladıktan yere wrt) foo ve çubuğu kullanarak arasındaki fark ne olduğunu anlamak istiyorum
class Test1: 
    bar = 10  
    def display(self,foo): 
     self.foo=foo 
     print "foo : ",self.foo #80 
    def display1(self): 
     print "bar: ", self.bar #10 
     print "again foo: ", self.foo #80 

if __name__ == '__main__': 
    test1 = Test1() 
    test1.display(80) 
    test1.display1() 
    print test1.bar #10 
    print test1.foo #80 

Birbiri ve tek fark, birisinin fonksiyonun içinde ve diğeri Sınıf'ın içinde olması ama ikisi de hala "örnek" değişkenidir. Peki bu iyi bir uygulama mı? Biraz aşağıda ekran işlevini değiştirirseniz

Ayrıca:

def display(self,foo): 
     self.foo=foo 
     foo = foo 
     print "self.foo : ",self.foo 
     print "foo : ",foo 

birisi piton ne fark/öneme bu self kelime ikisi foo arasına getiriyor gibi bu, nasıl gördüğünü lütfen açıklayabilir.

+4

Hayır, 'bar' değil * bir örnek değişkeni olan *. İkisi çok farklıdır, bu yüzden "iyi uygulama" ile ilgili değildir. Durumunuza uygun olan şey, çünkü farklı amaçlara hizmet ediyorlar. – phant0m

+1

Ayrıca 'self.bar' işlevi, 'bar' adı ilk önce örnek adında ve sonra sınıfta aranır. self.bar' çalışmaları * daima 'bar' bir örnek değişkendir anlamına gelmez' gerçeği. – ersran9

cevap

3

bar sınıfların beri. bir sınıf niteliktir Python nesneleridir, onlar da özniteliklere sahip olabilirler bar sadece bunun bir örneği değil, Test nesnesinde yaşanır.

Python öznitelik aramalarını çözme biçiminden dolayı, test1'un bar özniteliğine sahip gibi görünüyor, ancak öyle değil.

foodisplay(80) numaralı telefonu aradıktan sonra test1 örneğinde yaşar. Bu Test farklı örneklerini kendi foo özelliklerinde farklı değerlere sahip anlamına gelir. Tabii

, size daha sonra bir örneği özniteliği ile "geçersiz kılma", ama bu kafa karıştırıcı elde edebiliriz "paylaşılan varsayılan değer" bir tür olarak sınıf değişkenleri kullanabilirsiniz.

İkinci soru

def display(self,foo): 
    self.foo=foo 
    foo = foo 
    print "self.foo : ",self.foo 
    print "foo : ",foo 

Sadece yoldan bir ayrıntıyı alalım: self bir anahtar kelime değil, aynı zamanda onu "diyebiliriz, ilk argüman "öz" aramak için sadece kongre var İsterseniz "ya da" o "ya da" bar ", ama bunu tavsiye etmem.

Python yöntem, ilk değişken olarak adlandırılan nesneyi, geçirecektir.

def display(self,foo): 
Bu foo, görüntüleme örneği işlevinin ilk parametresinin adıdır.

self.foo=foo 

Bu size ilk argümanı olarak değere display() denilen hangi örneğinin adı "foo" ile niteliğini belirler. test1.display(80), self örneğinizi kullanarak test1, foo80 ve test1.foo, 80 olarak ayarlanacaktır.

Bu hiçbir şey yapmaz. İlk parametre foo'a başvurur.

sonraki iki hat yeniden foo değişken örneği ve ilk parametre foo referans.

4

bar sınıf özniteliğidir ve foo örnek özniteliğidir. Ana fark

>>> ins1 = Test1() 

ins1.bar çalışıyor o örneğe ekranı çağrı yalnızca foo örneğine sunulacak ederken bir sınıf niteliktir ve herkes tarafından paylaşıldığı için bar tüm sınıf örneklerine sunulacak olmasıdır örnekleri. Henüz tanımlanmamış olarak

>>> ins1.bar 
10 

Ama doğrudan buradan foo erişemez:

>>> ins1.foo 
Traceback (most recent call last): 
    File "<ipython-input-62-9495b4da308f>", line 1, in <module> 
    ins1.foo 
AttributeError: Test1 instance has no attribute 'foo' 

>>> ins1.display(12) 
foo : 12 
>>> ins1.foo 
12 

Eğer örnek daha sonra oluşturulan __init__ yöntemi içinde koyun edildiğinde bazı örnek niteliklerini başlatmak istiyorsanız .

class A(object): 
    bar = 10 
    def __init__(self, foo): 
     self.foo = foo #this gets initialized when the instance is created 
    def func(self, x): 
     self.spam = x #this will be available only when you call func() on the instance 
...   
>>> a = A(10) 
>>> a.bar 
10 
>>> a.foo 
10 
>>> a.spam 
Traceback (most recent call last): 
    File "<ipython-input-85-3b4ed07da1b4>", line 1, in <module> 
    a.spam 
AttributeError: 'A' object has no attribute 'spam' 

>>> a.func(2) 
>>> a.spam 
2 
+1

Sanırım * ana * fark, bir sınıf özniteliğinin "tümleşik" olması değil, tüm örneklerde kullanılabilir olmasıdır. – phant0m

1

Şahsen ben __init__ veya daha yukarıdaki örnekte olduğu bar gibi sınıf değişkenleri gibi diğer yöntemlerin içindeki örnek değişkenleri tanımlayan sevmiyorum.

Yine, kişisel olarak, sınıfın her üyesini en tepeye bakarak görmek isterim. Bir örnek değişkeni olarak kullandığınız bir sınıf değişkeni (genellikle yapmadığım bir şey) veya 'da tanımlanmış bir örnek değişkeni olup olmadığı, ilk bölümde incelenerek bir sınıfta neyin neyin tanımlanıp tanımlanmadığını anlamak kolaydır. sınıf tanımının

Bir değişkene bir sınıf üyesi olarak erişmeniz gerekmiyorsa (yani 'un __init__ yöntemiyle yazılmasını engellemek için yalnızca orada tanımlamanız gerekiyorsa, o zaman bunu açıklığa kavuşturabilirim. bir sınıf değişkeni olarak, daha sonra

. ne bar ile olan kitabımda tamam yapıyor Bu size sınıf yazmanın benim tercih edilen yolu olurdu.

class Test1: 

    def __init__(self): 
     self.foo = None 
     self.bar = 10 

    def display(self,foo): 
     self.foo=foo 
     print "foo : ",self.foo #80 

    def display1(self): 
     print "bar: ", self.bar #10 
     print "again foo: ", self.foo #80