2015-11-12 9 views
14

Enum को पायथन 3.4 में टाइप करने के लिए सबसे अच्छा अभ्यास क्या है और क्या ऐसा करने की संभावना भी है?पायथन एनम का विस्तार कैसे करें?

उदाहरण के लिए:

from enum import Enum 

class EventStatus(Enum): 
    success = 0 
    failure = 1 

class BookingStatus(EventStatus): 
    duplicate = 2 
    unknown = 3 

Traceback (most recent call last): 
... 
TypeError: Cannot extend enumerations 

इस समय वहाँ के सदस्यों के साथ एक आधार enum वर्ग बना सकते हैं और (उपरोक्त उदाहरण की तरह) अन्य enum कक्षाओं में इसका इस्तेमाल करने के लिए कोई संभव तरीका है। क्या पाइथन एनम्स के लिए विरासत को लागू करने का कोई और तरीका है?

+2

एक enum के पीछे विचार यह है कि आपके पास उस प्रकार के सभी मूल्यों की पूरी सूची है। यदि आप इसे बढ़ाते हैं और अधिक मूल्य जोड़ते हैं, तो आप enums की सबसे मौलिक संपत्ति तोड़ते हैं। – user2357112

+0

@ user2357112: thx, यह मेरी समस्या का उत्तर है। –

उत्तर

13

एक गणना को उप-वर्गीकरण केवल तभी अनुमति दी जाती है जब गणना किसी भी सदस्य को परिभाषित न करे।

सदस्यों को परिभाषित करने वाले एनम्स की उप-वर्गीकरण की अनुमति देना प्रकारों और उदाहरणों के कुछ महत्वपूर्ण आविष्कारों का उल्लंघन करेगा।

https://docs.python.org/3/library/enum.html#restricted-subclassing-of-enumerations

तो कोई, यह सीधे संभव नहीं है।

+0

क्या ऐसा करने के लिए कोई अन्य अंतर्निहित विधि है? –

+0

@ falek.marcin: आपको अधिक उपयोग जानकारी प्रदान करने की आवश्यकता होगी। आप 'बुकिंगस्टैटस' को सीधे 'एनम' से प्राप्त कर सकते हैं और नामों को पहले से दोहरा सकते हैं; यह हल्का अनावश्यक है, और वे अंतःक्रिया नहीं करेंगे (वे अलग-अलग प्रकार हैं), लेकिन यदि आप केवल मूल्यों के एक सेट का उपयोग कर रहे हैं, तो यह ठीक है। – ShadowRanger

+1

@ falek.marcin: शायद नहीं। मुझे लगता है कि आप सबसे अच्छी चीज एनम के एक और सरल कार्यान्वयन का उपयोग कर सकते हैं। उनमें से बहुत सारे हैं (http://stackoverflow.com/q/36932/3821804)। – GingerPlusPlus

3

असामान्य होने पर, कभी-कभी कई मॉड्यूल से एक enum बनाने के लिए उपयोगी होता है। aenum पुस्तकालय एक extend_enum समारोह के साथ इस का समर्थन करता है:

from aenum import Enum, extend_enum 

class Index(Enum): 
    DeviceType = 0x1000 
    ErrorRegister = 0x1001 

for name, value in (
     ('ControlWord', 0x6040), 
     ('StatusWord', 0x6041), 
     ('OperationMode', 0x6060), 
     ): 
    extend_enum(Index, name, value) 

assert len(Index) == 5 
assert list(Index) == [Index.DeviceType, Index.ErrorRegister, Index.ControlWord, Index.StatusWord, Index.OperationMode] 
assert Index.DeviceType.value == 0x1000 
assert Index.StatusWord.value == 0x6041 

प्रकटीकरण: मैं Python stdlib Enum के लेखक, enum34 backport, और Advanced Enumeration (aenum) पुस्तकालय हूँ।

7

एनम कक्षा को सीधे कॉल करना और श्रृंखला का उपयोग करना मौजूदा एनम के विस्तार (जुड़ने) की अनुमति देता है।

मैं कैनोपेन कार्यान्वयन पर काम करते समय enums को विस्तारित करने की समस्या पर आया। 0x1000 से 0x2000 की सीमा में पैरामीटर सूचकांक सभी कैनोपेन नोड्स के लिए सामान्य हैं, उदाहरण के लिए 0x6000 से सीमा के बाद, खुले कि क्या नोड एक ड्राइव, कब मॉड्यूल है निर्भर करता है आदि

nodes.py:

from enum import IntEnum 

class IndexGeneric(IntEnum): 
    """ This enum holds the index value of genric object entrys 
    """ 
    DeviceType = 0x1000 
    ErrorRegister = 0x1001 

Idx = IndexGeneric 

drives.py:

from itertools import chain 
from enum import IntEnum 
from nodes import IndexGeneric 

class IndexDrives(IntEnum): 
    """ This enum holds the index value of drive object entrys 
    """ 
    ControlWord = 0x6040 
    StatusWord = 0x6041 
    OperationMode = 0x6060 

Idx= IntEnum('Idx', [(i.name, i.value) for i in chain(IndexGeneric,IndexDrives)]) 
+1

शांत, धन्यवाद काम करने लगता है! – amohr

+1

बहुत चालाक। +1 –

+0

मैं एमआईटी-लाइसेंस प्राप्त [टाइफॉन लाइब्रेरी] (https://pypi.python.org/pypi/typhon) में अपने अंतिम स्निपेट से व्युत्पन्न कोड का उपयोग करना चाहता हूं। क्या आप एमआईटी-संगत लाइसेंस के तहत इसे कम करने के इच्छुक हैं? मैं पूर्ण एट्रिब्यूशन रखूंगा। – gerrit

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