2009-05-16 29 views
15

"Statik" tutmak istediğim karmaşık veri üyesi olan bir sınıfa sahibim. Bir işlevi kullanarak bir kez başlatmak istiyorum.Pythonic Yolu Başlatılıyor (Karmaşık) Statik Veri Üyeler

def generate_data(): 
    ... do some analysis and return complex object e.g. list ... 

class Coo: 
    data_member = generate_data() 
    ... rest of class code ... 

fonksiyon generate_data tamamlanması uzun zaman alıyor ve çalışan bir program kapsamında sabit kalır verileri döndürür: Pythonic böyle bir şey ne kadar. Her zaman Coo'nun başlatıldığı sınıfın kaçmasını istemiyorum.

Ayrıca, data_member'a __init__ numaralı telefona hiçbir şey atamadığım sürece, doğrulamak için "statik" kalacaktır? Coo'da bir yöntem data_member için bir değer eklerse (bu bir liste olduğunu varsayarsak) - bu ekleme örneklerin geri kalanında kullanılabilir mi?

Teşekkürler

+0

Bu kod hakkında Pythonic olmayan tek şey bir sınıf adı için küçük harfli bir tanımlayıcı kullanıyor. –

+0

@ Kart: Tabii ki haklısın, ben değiştirdim :) –

cevap

14

Her konuda haklısınız. data_member bir kez oluşturulacak ve coo'un tüm örnekleri için geçerli olacaktır. Herhangi bir örnek onu değiştirirse, bu değişiklik diğer tüm örneklere görünür olacaktır.

def generate_data(): 
    print "Generating" 
    return [1,2,3] 

class coo: 
    data_member = generate_data() 
    def modify(self): 
     self.data_member.append(4) 

    def display(self): 
     print self.data_member 

x = coo() 
y = coo() 
y.modify() 
x.display() 

# Output: 
# Generating 
# [1, 2, 3, 4] 
+0

Sınıfın dışındaki herhangi bir şey ne olacak? –

+0

@Omega: Aynı - sadece modül kapsamında "module_data = generate_data()" deyin. – RichieHindle

6

data_member = generate_data() sadece bir kez çalıştırılacaktır açıklamada, class coo: ... yürütüldüğünde:

İşte çıkış ucunda gösterilen ile, tüm bu gösteren bir örnek. Vakaların çoğunda sınıf ifadeleri modül düzeyinde gerçekleşir ve modül içe aktarıldığında yürütülür. data_member = generate_data() Yani sadece bir kez ilk kez coo sınıfı ile modül içe aktardığınızda yürütülür.

coo sınıfının tüm örnekleri data_member'u paylaşır ve yazarak erişebilir. için yapılan tüm değişiklikler hemen herhangi bir coo örneği tarafından görülebilir. Bir örnek kendi data_member özniteliğine sahip olabilir. Bu özellik self.data_member = ... yazılarak ayarlanabilir ve yalnızca bu örnek için görünür olacaktır. "Statik" data_member hala yazarak erişilebilir. Başkaları haklısın cevap gibi

13

- Ben farkında olmak bir şey daha ekleyeceğiz: Bir örnek nesnesi kendisi değiştirirse, o zaman modifikasyon tarafından görülür

self.data_member.append('foo') 

örneğin

için Örneklerin geri kalanı. Ancak daha sonra yeni bir örneği üye sınıf üyesi geçersiz kılar ve o örneğe, diğerlerini sadece görünür olan oluşturulur

self.data_member = new_object 

yaparsan. Fark, örneğin, self.data_member += 'foo' ve self.data_member = self.data_member + 'foo' gibi, her zaman kolay değildir.

Bunu önlemek için, nesneye her zaman (self'dan değil) olarak başvurmalısınız.

+0

+1, özellikle örnek özniteliği yerine bir sınıf özniteliği olarak başvurma hakkında birkaç iyi nokta. –

İlgili konular