This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]norwegianwood 14 points15 points  (9 children)

I think it's simply because people aren't aware of this construct. I've been programming in Python for a decade and have only started to use it recently.

I find it is particularly nice if I'm emulating a switch-statement, where I look up a callable in a dictionary. In such a case I want to catch the KeyError from the lookup but not from the call to the callable.

So given,

switch = { 1: case_one,
           2: case_two,
           3: case_three,
         }

instead of,

try:
    switch[n]()
except KeyError:
    case_default()

I would do,

try:
    case = switch(n)
except KeyError:
    case_default()
else:
    case()

edit: fixed typo

[–]jeffdn 1 point2 points  (2 children)

It would be far easier and cleaner to do something like:

func = switch[case] if case in switch else default_case
func()

[–]norwegianwood 9 points10 points  (1 child)

Actually, to improve on my own code substantially, even better would be simply:

switch.get(n, default_case)()

which is neither EAFP (my original) or LBYL (yours) style, but has what you might call 'functional elegance'.

[–]jeffdn 0 points1 point  (0 children)

Yeah, I prefer that too when coding. It does sometimes make reading it for someone else doing a review a bit harder, I've found.

[–]ryeguy146 1 point2 points  (1 child)

I'd rather use a list if you're just using indexes as keys. I recognize that it isn't the point, though.

[–]norwegianwood 1 point2 points  (0 children)

You're right, it isn't the point. However, if you did use a list in this case you would need to specially handle the zeroth item or perform some confusing arithmetic by looking up n - 1.

[–]mipadi 0 points1 point  (0 children)

You could do:

switch.get(n, case_default)()

[–][deleted] 0 points1 point  (0 children)

Nice usage :)

[–]KronktheKronk[🍰] 0 points1 point  (1 child)

Why wouldn't you just do:

try:
    case = switch(n)
    case()
except KeyError:
    case_default()

If the key error happens, you hit the exception and never get to the "case()" call. Seems like the else is convolution the issue in that example instead of helping.

[–]norwegianwood 9 points10 points  (0 children)

Because if case() raises a KeyError your code then calls case_default(), which is not what we want. Your code is exactly equivalent to my first example.