2008-09-20 5 views
6

मैं कुछ पायथन परियोजनाओं में एम्स का अनुकरण करने के लिए एक छोटी कक्षा का उपयोग कर रहा हूं। क्या कोई बेहतर तरीका है या क्या यह कुछ स्थितियों के लिए सबसे अधिक समझ में आता है?मुझे पाइथन में एनम के सर्वोत्तम अनुकरण और/या कैसे बचाना चाहिए?

कक्षा यहाँ कोड:

class Enum(object): 
'''Simple Enum Class 
Example Usage: 
>>> codes = Enum('FOO BAR BAZ') # codes.BAZ will be 2 and so on ...''' 
def __init__(self, names): 
    for number, name in enumerate(names.split()): 
     setattr(self, name, number) 
+3

http://stackoverflow.com/questions/36932/whats-the-best-way-to-implement-an-enum-in-python की डुप्लीकेट –

+0

सहमत। क्षमा करें, मुझे पहले यह पता होना चाहिए था। – Lanny

उत्तर

3

बहुत अच्छी चर्चा here है।

5

Enums भाषा में शामिल करने के लिए प्रस्तावित किया गया है से पहले, लेकिन (http://www.python.org/dev/peps/pep-0354/ देखें) को अस्वीकार कर दिया गया है, हालांकि मौजूदा संकुल आप के बजाय अपने खुद के कार्यान्वयन लिखने के इस्तेमाल कर सकते हैं देखते हैं:

2

enums करने के लिए अंतर्निहित तरीका है:

(FOO, BAR, BAZ) = range(3) 

जो छोटे सेट के लिए ठीक काम करता है, लेकिन कुछ कमियां भी हैं:

  • आप तत्वों की संख्या की गणना करने की जरूरत है हाथ से
  • आप मूल्य
  • छोड़ नहीं सकते हैं यदि आप ओ जोड़ते हैं ne नाम, आप भी सीमा संख्या

अजगर में एक पूरा enum कार्यान्वयन के लिए अद्यतन करने की आवश्यकता, देखें: http://code.activestate.com/recipes/67107/

+1

विशेष रूप से, यदि पायदान का आकार तत्व गणना से मेल नहीं खाता है तो पाइथन अपवाद उठाएगा। – cmcginty

3

क्या मैं अधिक बार देखते हैं कि यह शीर्ष स्तर के मॉड्यूल संदर्भ में है,:

FOO_BAR = 'FOO_BAR' 
FOO_BAZ = 'FOO_BAZ' 
FOO_QUX = 'FOO_QUX' 

... और बाद में ...

if something is FOO_BAR: pass # do something here 
elif something is FOO_BAZ: pass # do something else 
elif something is FOO_QUX: pass # do something else 
else: raise Exception('Invalid value for something') 

ध्यान दें किके उपयोग == के बजाययहां जोखिम ले रहा है - यह मानता है कि लोग स्ट्रिंग 'FOO_BAR' (जो सामान्यतः से इंटर्न किया जाएगा, is मिलान होगा, लेकिन निश्चित रूप से इसकी गणना नहीं की जा सकती है), और इसलिए संदर्भ के आधार पर उपयुक्त नहीं हो सकता है।

ऐसा करने का एक फायदा यह है कि कहीं भी देखकर उस स्ट्रिंग का संदर्भ संग्रहीत किया जा रहा है, यह तुरंत स्पष्ट है कि यह कहां से आया था; FOO_BAZ2 से बहुत कम संदिग्ध है।

कि इसके अलावा, दूसरी बात यह है कि आप जिस कक्षा का प्रस्ताव फिर से मेरी pythonic संवेदनशीलता नाराज split() का उपयोग है। क्यों शुरू करने के लिए बस एक tuple, सूची या अन्य गणना में गुजरना नहीं है?

4

सबसे आम enum केस गणना मूल्य है जो एक राज्य या रणनीति डिजाइन पैटर्न का हिस्सा हैं। Enums विशिष्ट राज्यों या विशिष्ट वैकल्पिक रणनीतियों का उपयोग करने के लिए हैं।इस मामले में, वे लगभग कुछ वर्ग परिभाषा

class DoTheNeedful(object): 
    ONE_CHOICE = 1 
    ANOTHER_CHOICE = 2 
    YET_ANOTHER = 99 
    def __init__(self, aSelection): 
     assert aSelection in (self.ONE_CHOICE, self.ANOTHER_CHOICE, self.YET_ANOTHER) 
     self.selection= aSelection 

फिर, इस कक्षा के ग्राहक में हैं।

dtn = DoTheNeeful(DoTheNeeful.ONE_CHOICE) 
1

मैं कुछ है कि S.Lott के जवाब की तरह एक बहुत लग रहा है के साथ शुरू किया, लेकिन मैं केवल 'str' और (पूरी वस्तु वर्ग के बजाय) 'eq' अतिभारित तो मैं प्रिंट और enum के मूल्य की तुलना कर सकते हैं।

class enumSeason(): 
    Spring = 0 
    Summer = 1 
    Fall = 2 
    Winter = 3 
    def __init__(self, Type): 
     self.value = Type 
    def __str__(self): 
     if self.value == enumSeason.Spring: 
      return 'Spring' 
     if self.value == enumSeason.Summer: 
      return 'Summer' 
     if self.value == enumSeason.Fall: 
      return 'Fall' 
     if self.value == enumSeason.Winter: 
      return 'Winter' 
    def __eq__(self,y): 
     return self.value==y.value 

प्रिंट (x) मूल्य के बजाय नाम उत्पन्न करेगा और स्प्रिंग वाले दो मूल्य एक दूसरे के बराबर होंगे।

>>> x = enumSeason(enumSeason.Spring) 
    >>> print(x) 
    Spring 
    >>> y = enumSeason(enumSeason.Spring) 
    >>> x == y 
    True 
संबंधित मुद्दे

 संबंधित मुद्दे