11

I'm using class enum.Enum in order to create a variable with selected members.

The main reason is to enable other developers in my team to use the same convention by selecting one of several permitted members for variable.

I would like to create a Boolean variable in the same way, enabling other developers to select either True or False.

Is it possible to define an enum which will receive True False options? Is there any better alternative?

The following options don't work:

boolean_enum = Enum('boolean_enum', 'True False')

boolean_enum = Enum('boolean_enum', True False)

2
  • 2
    what are you trying to do? Python already has a boolean. Commented Jul 20, 2015 at 5:43
  • I want other developers using my class to know this variable is boolean and has the True False options. I'm using this as part of a whole class of enums preserving a naming convention for variables that will be later converted to json format Commented Jul 20, 2015 at 5:49

3 Answers 3

9

Nowadays (python 3.6+) this could be much more conveniently achieved by using enum.Flag:

from enum import Flag

class Boolean(Flag):
    TRUE = True
    FALSE = False

An added benefit of enum.Flag over enum.Enum is that it supports (and is closed under) bit-wise operators (&,|,~) from the get-go:

>>> Boolean.TRUE & Boolean.FALSE
Boolean.FALSE
>>> Boolean.TRUE | Boolean.FALSE
Boolean.TRUE
>>> ~Boolean.FALSE
Boolean.TRUE

For more information see https://docs.python.org/3/library/enum.html#enum.Flag

Sign up to request clarification or add additional context in comments.

Comments

6
boolean_enum = Enum('boolean_enum', [('True', True), ('False', False)])

Checkout the documentation of this API: https://docs.python.org/3/library/enum.html#functional-api

If you just specify 'True False' for the names parameter, they will be assigned automatic enumerated values (1,2) which is not what you want. And of courase you can't just send True False without it being a string argument for the names parameter.

so what you want is one of the options that allow you to specify name and value, such as the above.

Edit:
When defined as above, the enum elements aren't accessible by boolean_enum.True (but they are accessible by boolean_enum['True'] or boolean_enum(True)).
To avoid this issue, the field names can be changed and defined as

Enum('boolean_enum', [('TRUE', True), ('FALSE', False)])

Then accessed as boolean_enum.TRUE or boolean_enum['TRUE'] or boolean_enum(True)

5 Comments

I used your command line, but when trying to the boolean_enum variable i get the following syntax error (on PyCharm IDE): "name expected"
@user3370773 as you can see here it works: tutorialspoint.com/…. Maybe something else is going on there. I'm not around PyCharm with Python3 to check, but I can't imagine there should be any problem with this specifically unique to PyCharm.
Can you please check this now: tutorialspoint.com/…. it doesn't seem to work for me when i try using the enum
@user3370773, Indeed there seem to be some issue, you can access the enum by boolean_enum['True'] or boolean_enum(True). Or you can call the fields with small-caps to avoid the issue, Enum('boolean_enum', [('true', True), ('false', False)]) and then access them as boolean_enum.true (or have it all caps, etc.)
Ok. Thanks. Can you please add that as an update to your answer so i can "accept" it.
0

Often I've started with a boolean variable (can_access = True|False) but then later needed to replace it with something more nuanced (can_access = True|False|'only_superuser'|'unless_leapday')

In your own code, it's easy to change this, but when you've released a public library people will have already written code expecting a boolean here. The problem of course is that in a boolean context, both 'only_superuser' and 'unless_leapday' will evaluate to True, but presumably 'only_superuser' should be False for naïve/existing implementations (and probably unless_leapday should be True).

So I wrote BooleanEnum which allows for a drop-in replacement for previous Boolean variables. If a value is a tuple, it is expected to be (BooleanValue, NormalLabel):

class CanAccess(BooleanEnum):
    TRUE = True
    FALSE = False
    ONLY_SUPERUSER = (False, 'only_superuser')
    UNLESS_LEAPDAY = (True, 'unless_leapday')

It becomes a drop-in replacement for if can_access: type of checks. Unfortunately, there's no way to do a drop-in for if can_access is True: types of checks.

The code is part of the music21 library under music21.common.enums.BooleanEnum, but you don't want that whole library as a dependency just for it, so here's the code (minus comments):

class BooleanEnum(Enum):
    @staticmethod
    def is_bool_tuple(v):
        if isinstance(v, tuple) and len(v) == 2 and isinstance(v[0], bool):
            return True
        else:
            return False

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return super().__eq__(other)
        v = self.value
        if v == other:
            return True
        elif self.is_bool_tuple(v):
            if v[0] is other:
                return True
            return v[1] == other
        return False

    def __bool__(self):
        v = self.value
        if self.is_bool_tuple(v):
            return v[0]
        return bool(self.value)

    def __repr__(self):
        return f'<{self.__class__.__name__}.{self.name}>'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.