Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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})


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"}).

share|improve this question
up vote 3 down vote accepted

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:

    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.

share|improve this answer
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 Jan 15 '13 at 15:13
@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 the dict. – Martijn Pieters Jan 15 '13 at 15:15
True. Given that the lookup is as easy as you assume in your code. – martiert Jan 15 '13 at 15:18
@martiert: The OP has not given us more than that. – Martijn Pieters Jan 15 '13 at 15:21

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.