2

I have read Replacements for switch statement in Python? and none of the answers seem to fully emulate a switch.

I know you can use if elif else or a dictionary but I'm wondering... is it possible in Python to fully emulate a switch including fall-through and default (without defining an enormous function before-hand)?

I am not overly concerned with performance and am mainly interested in readability and want to get the logical layout of a switch statement as in C-like languages in Python

Is this achievable or not?

Community
  • 1
  • 1
nettux
  • 5,270
  • 2
  • 23
  • 33
  • 2
    May I ask _why_ you're trying to do this? Generally there are better ways of tackling things in Python which is why the switch statement isn't part of the language... – Jon Cage May 08 '14 at 16:04
  • @JonCage I am asking purley out of curiosity but for the sake of argument; imagine that you had c code that you wanted to convert to python (for whatever reason) and it contained a ````switch```` satement which used fallthrough and default. – nettux May 08 '14 at 16:04
  • The documentation suggests that an `if ... elif ... else` block is the analog to a `switch / case` statement from other languages: https://docs.python.org/2/tutorial/controlflow.html#if-statements. Is there any particular reason you're not happy with that construction? – g.d.d.c May 08 '14 at 16:06
  • 1
    @g.d.d.c you don't get fall-through – nettux May 08 '14 at 16:07
  • What can we possibly add here, given that you've read everything from the previous question? PEP 3103 is pretty clear. – jonrsharpe May 08 '14 at 16:07
  • I'd be suprised if you could show us a concrete example of some C code which uses fall-through which couldn't be written better in some other way in Python without emulating a switch statement.. – Jon Cage May 08 '14 at 16:10
  • 4
    This question appears to be off-topic because it doesn't seem to be answerable. OP links several resources stating there is nothing EXACTLY like he's trying to do, then asks how to EXACTLY do it. – Adam Smith May 08 '14 at 16:16
  • @AdamSmith Read my question carefully. I link one post that gives answers that come close; I don't think any of them say that what I'm asking can't be done (correct me if I'm wrong :) ) but I'm asking 'is it possible' **not** 'how do I'. 'No it isn't possible' is a perfectly valid answer. – nettux May 08 '14 at 17:56
  • @JonCage You might be right. There well probably always be a better way from a performance stand-point but often when I'm making python scripts, performance is not my main concern. I don't care if it takes a couple of milliseconds longer to run as much as I care about readability; especially so if I or a co-worker may need to modify the script months or even years later. – nettux May 08 '14 at 18:01
  • @nettux443 if readability is your main concern then you should try to generate idiomatic Python, not Python that tries to be C. Someday you'll get a coworker that's never used a C-like language and they'll be going "WTF?" P.S. do you know how many bugs have been caused by lack of a `break` in switch statements? That's not something I'd want to emulate. – Mark Ransom May 08 '14 at 18:37
  • @MarkRansom I don't disagree with anything you've said but I'd still like to know if it could be done. – nettux May 08 '14 at 18:42
  • 1
    @nettux443 the consensus appears to be no, but I think closing the question to possible answers was a little drastic. – Mark Ransom May 08 '14 at 18:45

1 Answers1

2

As you don't want to use a dictionary or if elif else, the closest possible emulation, AFAIK, would be something like this:

class switch(object):
    def __init__(self, value):
        self.value = value
        self.fall = False

    def __iter__(self):
        """Return the match method once, then stop"""
        yield self.match
        raise StopIteration

    def match(self, *args):
        """Indicate whether or not to enter a case suite"""
        if self.fall or not args:
            return True
        elif self.value in args: # changed for v1.5, see below
            self.fall = True
            return True
        else:
            return False

import string
c = 'A'
for case in switch(c):
    if case(*string.lowercase): # note the * for unpacking as arguments
        print "c is lowercase!"
        break
    if case(*string.uppercase):
        print "c is uppercase!"
        break
    if case('!', '?', '.'): # normal argument passing style also applies
        print "c is a sentence terminator!"
        break
    if case(): # default
        print "I dunno what c was!"

@Author Brian Beck

@source: http://code.activestate.com/recipes/410692/ <- there are other suggestions there, you might want to check to see if any is good enough for you.

Note that you will have to use (or import this class switch)

Russell Borogove
  • 18,516
  • 4
  • 43
  • 50
Mansueli
  • 6,223
  • 8
  • 33
  • 57