Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Enum for constants #4

Closed
0xjac opened this issue Jun 23, 2017 · 2 comments
Closed

Use Enum for constants #4

0xjac opened this issue Jun 23, 2017 · 2 comments

Comments

@0xjac
Copy link

0xjac commented Jun 23, 2017

Use Enum rather than variables or magic numbers for status and actions

I.e. go from this

if self.actions[0] == "y": # Payout next note ( NV11 only )

To something like:

Definition

class Status(Enum):
    OK = (1, "debug message ok")
    FAIL = (2, "debug message fail")
    # ...

    def __init__(self, value, debug_message):
        self.value = value
        self.debug_message = debug_message

    def __int__(self):
        return self.value

    def __eq__(self, other):
        return self.value == other

Usage

from sys import stderr

from constants import Status, Action


try:
    self.print_debug(Status(events.event).debug_message)
except ValueError:
    print('Unknown status: {}'.format(events.event), out=stderr)

if events.event == Status.SOME_STATUS:
    pass
    # do something custom
elif events.event == Status.SOME_OTHER_STATUS:
    pass
    # do something different
#...

This also gets rid of the from constants import * which is never a good idea

Credit to florv for the Enum class definition

@0xjac 0xjac changed the title Use Enum for constants Use Enum for constants Jun 23, 2017
@tshabs
Copy link

tshabs commented Jun 25, 2017

Just trying to maintain compatibility where convenient. For enum could use https://pypi.python.org/pypi/enum34/ for py2 (providing it doesn't cause problems)

Minege added a commit that referenced this issue Jun 27, 2017
@0xjac
Copy link
Author

0xjac commented Jun 29, 2017

After some thinking I would advise to use the aenum package which is written by the same guy as the stdlib.enum and enum34 packages. It offers some advanced features and should solve all of the issues, including py2/py3 compatibility.

Here is a sample definition which suits your use case:

from aenum import IntEnum


class Status(IntEnum):
    _init_ = 'value', 'debug_message'
    
    OK = 1, "debug message ok"
    FAIL = 2, "debug message fail"

The _init_ takes a sequence of attributes to set on each Enum item. Then you just pass the actual values to each item.

Note that the first attribute passed to _init_ must be value.

I used IntEnum as the parent class in the example as this makes the enum a subclass of int as well but you can just use Enum if you prefer it.

In the end you should be able to use it like this with py2/py3:

assert Status.OK == Status(1)
assert Status.OK.name == 'OK'
assert Status.OK.value == 1
assert Status.OK.debug_message == "debug message ok"

@Minege Minege closed this as completed in cc5ff6d Jul 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants