Skip to content

Instantly share code, notes, and snippets.

@mikeckennedy
Last active August 21, 2019 04:55
Show Gist options
  • Save mikeckennedy/23ebca9ee1afd29f4534539d0ad3419d to your computer and use it in GitHub Desktop.
Save mikeckennedy/23ebca9ee1afd29f4534539d0ad3419d to your computer and use it in GitHub Desktop.
Could we easily add switch to the Python language? I think the answer is maybe yes!
# Here is an example of some syntax I'm proposing:
# See the github repo at https://github.com/mikeckennedy/python-switch
def test_switch():
num = 7
val = input("Enter a key. a, b, c or any other: ")
with Switch(val) as s:
s.case('a', process_a)
s.case('b', process_b)
s.case('c', lambda: process_with_data(val, num, 'other values still'))
s.default(process_any)
# process_a, process_b, and process_any are simple void/void methods
def process_a():
print("Found A!")
def process_b():
print("Found B!")
def process_any():
print("Found Default!")
def process_with_data(*value):
print("Found with data: {}".format(value))
# Here is a first pass implementation at adding switch
class Switch:
def __init__(self, value):
self.value = value
self.cases = {}
def default(self, func: Callable[[], None]):
self.case('__default__', func)
def case(self, key, func: Callable[[], None]):
if key in self.cases:
raise ValueError("Duplicate case: {}".format(key))
if not func:
raise ValueError("Action for case cannot be None.")
self.cases[key] = func
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
func = self.cases.get(self.value)
if not func:
func = self.cases.get('__default__')
if not func:
raise Exception("Value does not match any case and there is no default case: value {}".format(self.value))
func()
@mikeckennedy
Copy link
Author

Hi guys, thanks for the kind words and thoughts on this. Have a look here and let me know if you still feel that way:

https://github.com/mikeckennedy/python-switch#why-not-just-raw-dict

@pylang
Copy link

pylang commented Sep 14, 2017

Not sure where to post this thought ...

You know, switch/cases and singledispatch have something in common. The first can say "execute this function for a given value." The second says "execute this function for a given type".

It seems you could adapt your code to dispatch for certain types as well, e.g.:

with Switch(val) as s:
    s.case([int, float], process_a)
    s.case(list, process_b)

Thanks for this contrib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment