मैं सोच रहा हूं कि क्या मैं किसी उपयोगकर्ता से अपने कार्यों और कक्षाओं में विशिष्ट स्ट्रिंग इनपुट को लागू करने के लिए पायथन एनम का उपयोग कर सकता हूं, और स्वीकार्य मूल्यों के खिलाफ स्पष्ट जांच को कोड करने से बच सकता हूं।

तो इसके बजाय:

जैसे

utilities_supplied = {
    'electricity': 'Yes',
    'gas': 'No',
    'water': 'Yes',
}

def find_utility(utility):
    try:
        print(utilities_supplied[utility])
    except KeyError:
        raise KeyError(f'Please choose one of {utilities_supplied.keys()}, \'{utility}\' provided')

मैं यह करना चाहूंगा:


from enum import Enum
class Utility(Enum):
    electricity = 1
    gas = 2
    water = 3

Utility['electric']  
# not a member, I want this to raise an error which lists the acceptable options.

क्या एन्यूमर्स के लिए संभावित एन्यूमरेशन सदस्यों को सूचीबद्ध करने में त्रुटि उत्पन्न करना संभव है?

0
ac24 24 फरवरी 2020, 14:17
1
क्या आप स्पष्ट कर सकते हैं कि आपको क्या चाहिए? enum पहले से ही "विशिष्ट स्ट्रिंग इनपुट लागू करते हैं"। आपका उदाहरण कोड एक त्रुटि उत्पन्न करता है।
 – 
MisterMiyagi
24 फरवरी 2020, 14:36
मैं स्वीकार्य स्ट्रिंग इनपुट को सूचीबद्ध करने के लिए उठाई गई त्रुटि चाहता हूं, ताकि उपयोगकर्ता एनम सदस्यों में से किसी एक से मेल खाने के लिए अपने स्ट्रिंग इनपुट को समायोजित कर सकें।
 – 
ac24
24 फरवरी 2020, 14:42

2 जवाब

__getitem__ को ओवरराइट करने के लिए आप EnumMeta का इस्तेमाल कर सकते हैं, जो एनम से मान प्राप्त करता है:

import enum


class MyEnum(enum.EnumMeta):
    def __getitem__(cls, name):
        try:
            return super().__getitem__(name)
        except (KeyError) as error:
            options = ', '.join(cls._member_map_.keys())
            msg = f'Please choose one of {options}, \'{name}\' provided'
            raise ValueError(msg) from None


class Utility(enum.Enum, metaclass=MyEnum):
    electricity = 1
    gas = 2
    water = 3


fire = Utility['fire']
print(fire)

आउटपुट:

ValueError: Please choose one of electricity, gas, water, 'fire' provided
1
Maurice Meyer 24 फरवरी 2020, 15:09
धन्यवाद। मैंने आधार Enum वर्ग पर getattr को ओवरराइड करने का प्रयास किया था, लेकिन वांछित परिणाम नहीं मिला। यह एक अच्छा समाधान प्रतीत होता है।
 – 
ac24
24 फरवरी 2020, 15:53
1
@MauriceMeyer, क्या आप __missing__ का उपयोग करके कोई समाधान भी दिखा सकते हैं, और इसे पहले रख सकते हैं? उपवर्ग EnumMeta जैसा आपने काम किया है, लेकिन गलत होना आसान है। विवरण के लिए यह प्रश्न देखें।
 – 
Ethan Furman
24 फरवरी 2020, 18:34
एक कार्यान्वयन देखने में दिलचस्पी होगी जो यदि संभव हो तो उप-वर्गीकरण से बचा जाता है।
 – 
ac24
26 फरवरी 2020, 14:00

संपादित करें: जब मैं ValidatedEnum वर्ग को उपवर्गित करता हूं तो यह वास्तव में काम नहीं करता है। कोई भी सहायता कृतज्ञतापूर्वक प्राप्त हुई।

_missing_ का उपयोग करने वाला समाधान काफी सीधा था जो निकला! @EthanFurman विचार के लिए धन्यवाद।

from enum import Enum
class ValidatedEnum(Enum):
    electricity = 1
    gas = 2
    water = 3

    @classmethod
    def _missing_(cls, value):
        choices = list(cls.__members__.keys())
        raise ValueError("%r is not a valid %s, please choose from %s" % (value, cls.__name__, choices))

<ipython-input-1-8b49d805ac2d> in _missing_(cls, value)
      8     def _missing_(cls, value):
      9         choices = list(cls.__members__.keys())
---> 10         raise ValueError("%r is not a valid %s, please choose from %s" % (value, cls.__name__, choices))
     11 

ValueError: 'electric' is not a valid ValidatedEnum, please choose from ['electricity', 'gas', 'water']
0
ac24 28 फरवरी 2020, 13:54