2

I want to do something like that:

action = :default

if some_condition1:
    action = :do_something

if some_condition2:
    action = :do_other_thing

...

if action == :default:
   one_reaction()
elif action == :do_something:
   other_reaction()
...

What should I use to represent actions choice?

Variants that come to mind:

  • Create enumeration

    class MyActions:
        DEFAULT=1
        SO_SOMETHING=2
        SO_OTHER_THING=3
    

    inconvenient, need to scroll to and fro and "register" new action choices.

  • Use magic numbers. Not good.

  • Use strings.
Vi.
  • 29,583
  • 14
  • 78
  • 138

4 Answers4

4

"Symbols" in Lisp can be thought of, conceptually, as interned strings.

action = 'default'

if some_condition1:
    action = 'do_something'

if some_condition2:
    action = 'do_other_thing'

...

if action == 'default':
   one_reaction()
elif action == 'do_something':
   other_reaction()
...

Whenever you would use a symbol in Lisp, Python would use a string. Lisp has to make a distinction because it is homoiconic, but since Python isn't homoiconic, the distinction is unnecessary.

Alternatives

If you use numbers instead, then you lose REPL-ability. For example,

default = 1
do_something = 2
do_other_thing = 3

>>> x = default
>>> x
1 # is 1 default? I can't remember...

There are more sophisticated ways to do this, like creating special classes, but the small benefit is not worth the added complexity.

Dietrich Epp
  • 182,361
  • 34
  • 307
  • 387
3

An instance of the following class will return the name of any attribute you call from it. Creating a variable k or something would make accessing it simple.

class LispKeyword(object):
    def __getattribute__(self, name):
        return name

>>> k = LispKeyword()
>>> k.blarg
'blarg'
>>> k.what
'what'
Drakekin
  • 1,301
  • 1
  • 11
  • 22
0

For the code you've provided you can set a variable to a function that needs to be called. For a more general solution you can use strings or an enum. See also https://stackoverflow.com/a/3743555/113586

Community
  • 1
  • 1
wRAR
  • 23,485
  • 4
  • 77
  • 94
0

The idea of adding something-like-enum to the language is under discussion right now on the python-ideas list "constant/enum type in stdlib", with multiple designs and pure-Python implementations being tossed around and picked over. In the previous round of discussion, Guido and almost everyone else agreed something was worth adding, but nobody ever decided what to add.

So, I think you could say that the idiomatic way to do enum constants hasn't actually been invented yet.

It's worth skimming that thread to get a sense of what's considered idiomatic, and what the obvious way to do it is if you're Dutch, and so on. And if you do want to use enums, it's even more worth skimming before choosing an implementation.

Meanwhile, if you want to know what's idiomatic in the distant past of, say, February 2013, I'd agree with Dietrich Epp that strings are almost always the right choice for problems of this type.

He explains why the performance issues aren't an issue in Python, but there's one more thing people always bring up that I want to dismiss:

thingy = 'mokney'
# ...
if thingy == 'gorilla': do_gorilla()
elif thingy == 'monkey': do_monkey()
else: do_default()

If you used some kind of strict enum, this couldn't happen—or, at least, you could protect against it by putting an assert isinstance(thingy, Primate) before the if/elif chain.

Which all sounds great, until you look at this line:

thigny == 'monkey'
abarnert
  • 313,628
  • 35
  • 508
  • 596