This is less a question about the nature of duck typing and more about staying pythonic, I suppose.
First of all - when dealing with dicts, in particular when the structure of the dict is fairly predictable and a given key is not typically present but sometimes is, I first think of two approaches:
if myKey in dict: do_some_work(dict[myKey]) else: pass
And of course Ye Olde 'forgiveness vs permission' approach.
try: do_some_work(dict[myKey]) except KeyError: pass
As a journeyman Python guy, I feel like I see the latter preferred a lot, which only feels odd I guess because in the Python docs
try/excepts seem to be preferred when there is an actual mistake, as opposed to an, um… absence of success?
If the occasional dict does not have key in myDict, and it is known that it will not always have that key, is a try/except contextually misleading? This isn't a programming error, it's just a fact of the data - this dict just didn't have that particular key.
This seems particularly important when you look at the try/except/else syntax, which looks to be really useful when it comes to making sure that try isn't catching too many errors. You're able to do something like:
try: foo += bar except TypeError: pass else: return some_more_work(foo)
Isn't that going to lead to swallowing all kinds of weird errors that are probably the result of some bad code? The above code might just be preventing you from seeing that you're trying to add
I realize the above example is something of a straw-man argument, and is in fact intentionally bad. But given the pythonic creed of
better to ask forgiveness than permission I can't help but feel like it begs the question of where the line in the sand actually is between correct application of if/else vs try/except is, in particular when you know what to expect out of the data you're working with.
I'm not even talking about speed concerns or best practice here, I'm just sort of quietly confused by the perceived Venn diagram of cases where it looks like it could go either way, but people err on the side of a try/except because 'someone somewhere said it was Pythonic'. Have I drawn the wrong conclusions about the application of this syntax?