I have a function that accepts either a string or a dictionary as an argument. That is, it can be called as either:
lookup_person({name: "John Smith", age: 57})
or
lookup_person("John Smith")
My first inclination is to use type
or isinstance
to distinguish the type of the argument, but I've seen a lot of ink spilled over whether and when rigid type detection is appropriate. The prevailing wisdom I've read suggests that I should test if my object implements some interface, but testing for particular string or dictionary methods seems significantly less safe than simply testing if the type of the object is a string or dictionary.
Is it possible to employ duck typing here, and is it appropriate to do so? Or do I have a larger problem, and my approach here somehow fundamentally not Pythonic?
EDIT: To clarify, passing a dictionary is the "typical" use. Passing in a string is simply an API shorthand for a single-entry dictionary with name
, i.e., lookup_person({name:"John Smith"})
.
1 Answer 1
You definitely can use duck typing here, although I'm not sure why you want to accept both a dictionary and a string in this case.
I'd ask for forgiveness instead of permission in this case:
try:
name = person['name'] # treat as dictionary
except TypeError:
name = person # assume it's a string instead
but do review if asking for permission might be faster for your case.
-
I agree. Ideally I would have had two functions: lookup_person_dict, lookup_person_string and force the user to be specific. The problem I find with this is that you basically use a try/except block for control flow, is a big no-no in my eyes. However, having a function which accepts both string and hashmaps is also a no-no in my eyes, and so this exception flow is the cleanest alternative I can think of at least.martiert– martiert2013年01月15日 15:13:43 +00:00Commented Jan 15, 2013 at 15:13
-
2@martiert: No, ideally you force the user to use
lookup_person(somedict['name'])
; simplify the API as there is no need for the rest of thedict
.Martijn Pieters– Martijn Pieters2013年01月15日 15:15:05 +00:00Commented Jan 15, 2013 at 15:15 -
True. Given that the lookup is as easy as you assume in your code.martiert– martiert2013年01月15日 15:18:28 +00:00Commented Jan 15, 2013 at 15:18
-
@martiert: The OP has not given us more than that.Martijn Pieters– Martijn Pieters2013年01月15日 15:21:59 +00:00Commented Jan 15, 2013 at 15:21