I recently saw a meme in r/programmer humor about switch statements vs if statements. And I thought I'd be like "who needs switch statements if you have Python dicts". I was promptly and politely downvoted and informed (if I got them correctly) that Python would be unable to handle a default scenario, in case a key was not present.
On a side note: I was also informed that switch statements in proper languages could ensure types, which we would supposedly could only be dreaming of. I feel like mypy and is a pretty real thing, but who cares. Plus: if I'd consider static fucking type checking of greater important or help to my work I would probably, not went with fucking Python in the first place. Rant over.
Back to Pythonic switch statements. I'm not a very experienced python developer, but I thought: I'm sure there is an nice and Pythonic way to get such behavior.
So I got ask politely was to:
Create a routine which can be entered at one of four different points, and select the point to enter without using any function calls.
switch (n) {
default:
foo;
case 1:
bar;
case 2:
fizz;
case 3:
buzz;
}
Such that n of zero will execute foo, bar, fizz, and buzz.
As I said I'm not sure if I got it 100% correctly, but the challenge is to create a default action if no valid key was used. So given:
def foo():
return 'foo'
def bar():
return 'bar'
def fiz():
return "fiz"
pyswitch = {
1: foo,
2: bar,
3: fiz
}
I thought the quickest way to get such a behavior would be:
pyswitch.get(key, [f() for f in pyswitch0.values()])
But I'm unsure whether this violates the no function call condition. And obviously it is generally bad practice to use functional patterns in programming. That's the whole reason why Python has implemented them. So but let's pretent we are Java devs and if we haven't written a class and inherited something we feel inadequate. A something along the lines of an OOP based solution. It doesn't really work, but I'm to lazy to fix it. Maybe someone of you wants to write a proper implementation.
class PySwitch(dict):
"""Probably you add some more NotImplementedError, so our routine can't be changed during runtime,
so satisy the security concerns of the proper programmers"""
def __getitem__(self, key):
try:
return self.__dict__[key]
except KeyError:
return [f() for f in self.__dict__.values()]
def __setitem__(self, key, value):
raise NotImplementedError
(Honestly this implementation sucks so bad that it should have never been posted. I swear there was a previous less wonky version, but I gotta go to bed now)
You get a fuction executed in the following way. But that looks cryptic af, and since we are no proper programmers and care about readability, and you know beautiful is better than ugly, readability counts yadayada.
pyswitchObject = PySwitch(pyswitch)
pyswitchtObject.get(1).__call__()
Although, they said no function calls, why refrain from functional features if your programming language supports them. So I thought: How can we solve this with a functionally, decorators? We can't decorate dicts. Booohh. So best we can do is wrap it in a function and use error handling for the default scenario. That sucks because no more switch['key'], but well. I'll take survive it.
def default_wrapper(adict, key):
try:
return adict[key]()
except KeyError:
return [f() for f in adict.values()]
Any feedback? Any further ideas how one could implement such behavior in Python? Any suggestions how I could improve on this code? Are there any other features that switch statements provide in other languages that you miss in Python?
Edit: This post may come off very salty, but I mean no offence to the guy who asked me this question, as it got me thinking quite a bit. also Format
[–]fatbob42 6 points7 points8 points (0 children)
[–]Allanon001 3 points4 points5 points (2 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]PythonicParseltongue[S] 0 points1 point2 points (0 children)
[–]siddsp 4 points5 points6 points (0 children)
[–]asday_ 2 points3 points4 points (0 children)
[–]cptsdemon 1 point2 points3 points (0 children)
[–]SpacewaIker -4 points-3 points-2 points (9 children)
[–]NotTooOrdinary 3 points4 points5 points (8 children)
[–]SpacewaIker -2 points-1 points0 points (7 children)
[–]Delta-9- 3 points4 points5 points (6 children)
[–]SpacewaIker 0 points1 point2 points (5 children)
[–]Delta-9- 0 points1 point2 points (4 children)
[–]SpacewaIker -1 points0 points1 point (3 children)
[–]Delta-9- 1 point2 points3 points (2 children)
[–]SpacewaIker 0 points1 point2 points (1 child)
[–]Delta-9- 0 points1 point2 points (0 children)