3

I want to initialise a User class with attributes whose value is taken from a finite and immutable set of possible values (e.g., types of user, short list of countries...). What is the best approach to do that in Python?

class User(object):
    def __init__(self, type, country):
        self.type = type # Possible values: [Consumer, Producer]
        self.country = country # Possible values: [UK, USA, Japan, France]

It is probably obvious, but the reason for me to formally limit to this set of possible values is mainly to avoid/spot errors.

I have looked at various explanations on list and Enum in Python (e.g., How to implement an Enum in Python), but I am not sure if it is the right way to go considering my needs. Especially, it seems – from what I have read – that Enum is to store a list of constants (User.type as CONSUMER and PRODUCER)... but I would like to be able to use the values directly in the output (so the uppercase seems weird). And I am not sure whether a numeric equivalent for each value (CONSUMER=1...) would be of much use for me.

EDIT: I should probably add that the real values in my application are in French and include thus non-ASCII characters (e.g., États-Unis). Going the Enum way seems to make it impossible to keep these characters and would mean to then "translate" the value to a "localised" value, which looks to me like a lot of trouble for a short list.

Community
  • 1
  • 1
iNyar
  • 512
  • 6
  • 20

1 Answers1

3

First of all how were you thinking of making a variable out of États-Unis anyway ? Putting in a list? In any case, Enums are a good way to go,

To limit the choices add validation for the passed arguments UserType and Country

Secondly you can directly compare enums eg COUNTRY.US == COUNTRY.UK #returns False so it doesn't matter what actual values those enums have.

If you still want to retrieve the value then you can get it from Country.US.value

class Country(Enum):
    US = 'États-Unis'
    UK = 'Royaume-Uni'


class UserType(Enum):
    CONSUMER = 1
    PRODUCER = 2


class User(object):
    def __init__(self, type, country):
        if not isinstance(type, UserType):
            raise Exception
        self.type = type # Possible values: [Consumer, Producer]

        if not isinstance(country, Country):
            raise Exception
        self.country = country # Possible values: [UK, USA, Japan, France]




==> Country.UK == Country.US
==> False

==> print(Country.US.value)
==> 'États-Unis'
Kashif Siddiqui
  • 1,171
  • 10
  • 23
  • Great! Thank you! I didn't understand I could assign a text value to each `Enum` key! Small clarification: I suppose I have to import the `Enum` module, or not? From `enum`, `enum34`, `aenum`? – iNyar Mar 27 '17 at 09:08
  • Yep, `from enum import Enum` I think. There are other fancy kinds of enums in that module as well if you are interested, check out [Enum docs](https://docs.python.org/3.4/library/enum.html) – Kashif Siddiqui Mar 28 '17 at 00:35