2017-06-27 7 views
16

मैंने अभी पाइथन में Enum बेस क्लास के अस्तित्व की खोज की है और मैं कल्पना करने की कोशिश कर रहा हूं कि यह मेरे लिए उपयोगी कैसे हो सकता है।एक पायथन एनम के साथ एक स्ट्रिंग की तुलना कैसे करें?

चलो कहते हैं कि मैं एक यातायात प्रकाश स्थिति को परिभाषित करते हैं:

from enum import Enum, auto 

class Signal(Enum): 
    red = auto() 
    green = auto() 
    orange = auto() 

मान लीजिए कि मैं उदाहरण brain_detected_colour = "red" के लिए मेरे कार्यक्रम में कुछ सबसिस्टम से जानकारी प्राप्त, एक स्ट्रिंग एक रंग नाम का प्रतिनिधित्व के रूप में, करते हैं।

मैं इस स्ट्रिंग की तुलना अपने ट्रैफिक लाइट सिग्नल से कैसे करूं?

जाहिर है, brain_detected_colour is Signal.redFalse है, क्योंकि Signal.red एक स्ट्रिंग नहीं है।

Signal(brain_detected_colour) is Signal.redValueError: 'red' is not a valid Signal के साथ विफल रहता है।

उत्तर

18

कोई instance of an Enum नहीं बनाता है। Signal(foo) सिंटैक्स का उपयोग मूल्य से एनम सदस्यों तक पहुंचने के लिए किया जाता है, जिनका उपयोग auto() होने पर किया जाने वाला नहीं है।

हालांकि एक की तरह एक एक dict में एक मूल्य का उपयोग होता access Enum members करने के लिए एक स्ट्रिंग का उपयोग कर सकते हैं, का उपयोग कर वर्ग कोष्ठक:

Signal[brain_detected_colour] is Signal.red 

एक और संभावना एक Enum सदस्य की name को स्ट्रिंग तुलना करने के लिए किया जाएगा:

# Bad practice: 
brain_detected_colour is Signal.red.name 

लेकिन यहाँ, हम Enum सदस्यों के बीच पहचान परीक्षण कर रहे हैं नहीं है, लेकिन तार की तुलना, तो यह एक समानता परीक्षण का उपयोग करना बेहतर अभ्यास है:

# Better practice: 
brain_detected_colour == Signal.red.name 

(स्ट्रिंग्स के बीच पहचान तुलना string interning पर धन्यवाद, जिस पर निर्भर नहीं किया जाना बेहतर है। धन्यवाद मुझे उस के बारे में पता करने के लिए @mwchase और @Chris_Rands)

फिर भी एक और संभावना को स्पष्ट रूप से उनके नाम Enum बनाते समय के रूप में सदस्य मूल्यों को निर्धारित करने होगा:।

class Signal(Enum): 
    red = "red" 
    green = "green" 
    orange = "orange" 

(एक विधि के लिए this answer देखें यह स्वचालित करने के लिए।)

फिर, Signal(brain_detected_colour) is Signal.red मान्य होगा।

+6

'brain'detected_colour में' is' का उपयोग करना Signal.red.name' जोखिम भरा है; यह '==' का उपयोग करना बेहतर होगा। – mwchase

+0

@mwchase क्या आप समझा सकते हैं, ताकि मैं अपना जवाब संपादित कर सकूं और स्पष्टीकरण जोड़ूं? – bli

+4

आप स्ट्रिंग इंटर्निंग पर भरोसा कर रहे हैं, अस्पष्ट कार्यान्वयन विवरण http://guilload.com/python-string-interning/, कभी भी 'is' का उपयोग न करें जब तक कि आपको वास्तव में वस्तुओं की पहचान की तुलना करने की आवश्यकता न हो –

5

यह auto() के लिए अपने मूल्य के रूप में enum सदस्य का नाम वापसी (जो auto section of the docs में संभव है:

>>> class AutoName(Enum): 
...  def _generate_next_value_(name, start, count, last_values): 
...   return name 
... 

>>> class Ordinal(AutoName): 
...  NORTH = auto() 
...  SOUTH = auto() 
...  EAST = auto() 
...  WEST = auto() 
... 

>>> list(Ordinal) 
[<Ordinal.NORTH: 'NORTH'>, <Ordinal.SOUTH: 'SOUTH'>, <Ordinal.EAST: 'EAST'>, <Ordinal.WEST: 'WEST'>] 

इस संस्करण की आवश्यकता है पायथन 3.6, या aenum 2.0 (aenum पायथन के साथ 2.7 के रूप में पुराने काम करता है)।

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

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