2010-02-17 18 views
9

Python, bir dersin içeriğini sizin için listeleyecek kullanışlı dir() işleviyle birlikte gelir. Örneğin, bu sınıf için:Bir sınıfın nitelikleri üzerinde, tanımlandıkları sırada nasıl yineleme yapılır?

class C: 
    i = 1 
    a = 'b' 

dir(C) bu harika

['__doc__', '__module__', 'a', 'i'] 

dönmek fakat 'a' ve 'i' sırası onlar tanımlandı sonra sırası şimdi farklı nasıl fark ederdi

.

C'nin özniteliklerinin üzerinde tanımlanabilir (olası yerleşik & modül özniteliklerini göz ardı ederek) tanımlandıkları sıraya göre nasıl yineleyebilirim? Yukarıdaki C sınıfı için, 'i' ve daha sonra 'a' olacaktır.

Ek: - Bazı serileştirme/günlüğe kaydetme kodları üzerinde çalışıyorum. Öznitelikleri tanımlandıkları sıraya serileştirmek istiyorum; böylece çıktı, sınıfı oluşturan kodun benzeri olacaktır.

+0

Niçin tanımlanmış siparişler hiç önemli değil? Bu durumda siparişin önemi yoktur. Alabilirsen bu bilgiyi nasıl kullanırdın? –

+0

Sınıfın sınıflarını veya örneklerini serileştiriyor musunuz? Örneğinizde, "a" ve "i" sınıf öznitelikleridir. Bunların örnek nitelikleri olduğunu düşünüyorsanız, bunları '__init__'' self.a = 'b'' ve 'self.i = 1' kullanarak tanımlamanız gerekir. – PaulMcG

+0

Bunlar, örnek değişkenleri kadar kullanışlı olmayan sınıf düzeyi özniteliklerdir. Neden sınıf özelliklerinin sırasını korumaya çalışıyorsunuz? Örnek değişkenlerin sırasını korumak daha iyi olmaz mıydı?Neden sınıf düzeyinde değişkenlerle püf noktaları yapmaya çalışıyorsun? –

cevap

7

Bunun Python 2.x'te mümkün olduğunu düşünmüyorum. Sınıf üyeleri, __new__ yöntemine sağlandığında, bir sözlük olarak verilmiştir, bu nedenle sipariş bu noktada zaten kaybolmuştur. Bu nedenle, metasınıflar bile size yardımcı olamaz (kaçırdığım ek özellikler olmadıkça).

Python 3'te, yeni bir __prepare__ özel yöntemini kullanarak özel bir dict oluşturmak için kullanabilirsiniz (bu, PEP 3115 numaralı örnekte bile verilmiştir).

+0

Django bunu nasıl yapıyor (Python 2.x ve üstü): https://github.com/django/django/blob/stable/1.3.x/django/db/models/fields/__init__.py#L56 – tobych

+0

Henüz Django kullanmamıştım, ama sanırım bu her ödevde yeni bir 'Saha' örneği oluşturuyor mu? İyi bir çözüm gibi geliyor. – nikow

+0

Evet, Django'nun yaptığı şey bu. – tobych

1

Bu bilgiler erişilebilir değildir, çünkü öznitelikler, doğası gereği sırasız olan bir dikte ile depolanır. Python bu bilgiyi herhangi bir yerden siparişle ilgili saklamaz. Eğer seri biçimi belirli bir sırayla şeyleri saklamak istiyorsanız

sen açıkça sipariş belirtmek istiyorum. Bilmediğiniz veya önem verdiğiniz şeyleri içeren dir'u kullanmazsınız, hangilerinin seri hale getirileceğini tanımlayan bir liste (ya da her neyse) açıkça belirtirsiniz. Benim çözüm

class Q: 
def __init__(self): 
    self.a = 5 
    self.b = 10 

if __name__ == "__main__": 
    w = Q() 
    keys = w.__dict__.keys() 
    for k in keys: 
     print "Q.%s = %d"%(k,w.__dict__[k]) 

Çıktı değildir etkili olabilir böylece

2

Ben, Python yeniyim:

Q.a = 5 
Q.b = 10 
+0

Bu, siparişi korumaz. –

2

sınıfınızda bu yöntemi koymak

def __setattr__(self, attr, value): 
    if attr not in dir(self): 
     if attr == "__ordered_fields__": 
      super.__setattr__(self, attr, value) 
     else: 
      if not hasattr(self, "__ordered_fields__"): 
       setattr(self, "__ordered_fields__", []) 
      self.__ordered_fields__.append(attr) 
      super.__setattr__(self, attr, value) 

ve

alanları sırayla al, sadece şu gibi bir şey yap:

print(self.__ordered_fields__) 
İlgili konular