2010-02-17 17 views
9

पायथन आसान dir() फ़ंक्शन के साथ आता है जो आपके लिए कक्षा की सामग्री सूचीबद्ध करेगा। उदाहरण के लिए, इस वर्ग के लिए:कक्षा के गुणों पर पुनरावृत्ति कैसे करें, क्रम में उन्हें परिभाषित किया गया था?

class C: 
    i = 1 
    a = 'b' 

dir(C)

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

वापसी होगी यह महान है, लेकिन ध्यान दें कि किस 'a' और 'i' के आदेश अब अलग तो क्रम में वे में परिभाषित किया गया है

मैं सी के गुणों को कैसे पुन: सक्रिय कर सकता हूं (संभावित रूप से अंतर्निहित दस्तावेज़ & मॉड्यूल विशेषताओं को अनदेखा कर रहा है) जिन्हें वे परिभाषित किए गए थे? उपरोक्त सी कक्षा के लिए, 'i' होगा 'a'

अनुपूरक: - मैं कुछ क्रमबद्धता/लॉगिंग कोड पर काम कर रहा हूं जिसमें मैं परिभाषित क्रम में गुणों को क्रमबद्ध करना चाहता हूं ताकि आउटपुट कक्षा के समान कोड के समान होगा।

+0

आदेश को परिभाषित करने का आदेश बिल्कुल क्यों होगा? आदेश इस मामले में अप्रासंगिक है। यदि आप इसे प्राप्त कर सकते हैं तो आप उस जानकारी का उपयोग कैसे करेंगे? –

+0

क्या आप कक्षा के वर्ग या उदाहरणों को क्रमबद्ध कर रहे हैं? आपके उदाहरण में, 'ए' और' i' कक्षा गुण हैं। यदि आपका मतलब यह है कि उदाहरण गुण हैं, तो आपको उन्हें 'self.a =' b'' और 'self.i = 1' का उपयोग करके' __init__' में परिभाषित करना चाहिए। – PaulMcG

+0

ये क्लास-स्तरीय विशेषताएं हैं, जो इंस्टेंस चर के रूप में उपयोगी नहीं हैं। आप कक्षा गुणों के क्रम को संरक्षित करने की कोशिश क्यों कर रहे हैं? उदाहरण चर के क्रम को संरक्षित करना बेहतर नहीं होगा?आप कक्षा-स्तर चर के साथ चाल करने की कोशिश क्यों कर रहे हैं? –

उत्तर

7

मुझे नहीं लगता कि यह पायथन 2.x में संभव है। जब कक्षा के सदस्यों को __new__ विधि प्रदान की जाती है तो उन्हें एक शब्दकोश के रूप में दिया जाता है, इसलिए उस बिंदु पर आदेश पहले ही खो गया है। इसलिए यहां तक ​​कि metaclasses भी आपकी मदद नहीं कर सकते हैं (जब तक कि अतिरिक्त सुविधाओं को याद नहीं किया जाता है)।

पायथन 3 में आप आदेशित आदेश बनाने के लिए नए __prepare__ विशेष विधि का उपयोग कर सकते हैं (इसे PEP 3115 में एक उदाहरण के रूप में भी दिया जाता है)।

+0

यहां यह है कि Django यह कैसे करता है (पायथन 2.x और ऊपर): https://github.com/django/django/blob/stable/1.3.x/django/db/models/fields/__init__.py#L56 – tobych

+0

मैंने अभी तक Django का उपयोग नहीं किया है, लेकिन मुझे लगता है कि यह आवश्यक है कि प्रत्येक असाइनमेंट में हम एक नया 'फ़ील्ड' उदाहरण बनाते हैं? एक अच्छा समाधान की तरह लगता है। – nikow

+0

हां, यही Django करता है। – tobych

1

यह जानकारी सुलभ नहीं है, क्योंकि गुण एक ताना में संग्रहीत हैं, जो मूल रूप से अनियंत्रित है। पाइथन इस जानकारी को कहीं भी ऑर्डर के बारे में संग्रहीत नहीं करता है।

आप अपने क्रमबद्धता प्रारूप एक निश्चित क्रम में बातें संग्रहीत करना चाहते हैं आप कि आदेश स्पष्ट रूप से निर्दिष्ट करना होगा। आप dir का उपयोग नहीं करेंगे, जिसमें ऐसी चीजें हैं जिन्हें आप नहीं जानते या उनकी परवाह नहीं करते हैं, आप स्पष्ट रूप से एक सूची (या जो कुछ भी) को क्रमबद्ध करने का वर्णन करते हैं।

2

मैं अजगर में नए हूँ, इसलिए मेरा समाधान प्रभावी नहीं

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]) 

आउटपुट है हो सकता है:

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

यह आदेश को संरक्षित नहीं करता है। –

2

अपनी कक्षा में इस विधि डाल

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) 

और करने के लिए फ़ील्ड क्रम में प्राप्त करें, बस कुछ ऐसा करें:

print(self.__ordered_fields__) 
संबंधित मुद्दे