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

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:

    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
    Commented 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 the dict. Commented Jan 15, 2013 at 15:15
  • True. Given that the lookup is as easy as you assume in your code.
    – martiert
    Commented Jan 15, 2013 at 15:18
  • @martiert: The OP has not given us more than that. Commented Jan 15, 2013 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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