2

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

apsillers
  • 5,223

1 Answers1

3

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.