Writing methods that accept either a single item or an iterable in Python
<p>I have a design issue. I would like to write a method accepts either a single object or an iterable of objects. For example, lets say I have the class Dog:</p>

<pre><code>class Dog(object):
    """
    An animal with four legs that may slobber a lot
    """
    def __init__(self, name="Fido"):
       self.name = name
</code></pre>

<p>Now let's say that I have a class that uses the Dog class, say DogWalker:</p>

<pre><code>class DogWalker(object):
    """
    Someone who cares for Fido when Human Companion is not available
    """
    def __init__(self):
        self.dogs_walked = 0
        self.dogs_watered = 0

    def walk(self, dogs):
        """
        Take a dog for a walk
        """
        # This is not Pythonic
        if isinstance(Dog, dogs):
            # Walk a single dog
            pass
            self.dogs_walked +=1
        else:
            # walk lots of dogs
            pass


    def water(self, dogs):
        """
        Provide water to dogs
        """
        # More pythonic
        try:
            # Try to water single dog
            ...
            self.dogs_walked += 1
        except  AttributeError:
            # Try to water lots of dogs
            pass
</code></pre>

<p>In the example, above I've implemented two methods walk and water. The water method is more pythonic in that it uses Duck Typing. However, I'd like to take the conversation a bit further. Let's say I have a care taker class that can water different types of animals:</p>

<pre><code>class CareTaker(object):
    """
    Someone who cares for things
    """
    def __init__(self):
        self.things_watered = 0

    def water(self, things):
        """
        Provide water to a thing
        """
        # Here is where I need help!
        # 1. I need to figure out if things is a single item or iterable
        # 2. If thing is a single item I need to figure out what type of thing a thing is
        # 3. If thing is an iterable, I need to figure out what type of things are in the iterable.
        pass
</code></pre>

<p>Now, one thing that occurred to me is that each thing could know how to water itself, and then the care taker would only need to call the things water method. For example:</p>

<pre><code>class CareTaker(object):
    """
    Someone who cares for things
    """
    def __init__(self):
        self.things_watered = 0

    def water(self, thing):
        """
        Provide water to a thing
        """
        result = thing.water()
        self.things_watered += 1
        return result
</code></pre>

<p>That way using the code might look like:</p>

<pre><code>ct = CareTaker()
dog = Dog()
bird = Bird()
water_dog = ct.water(dog)
water_bird = ct.water(bird)

things = [dog, bird]

for thing in things:
    ct.water(thing)
</code></pre>

<p>I have a few other ideas, but I would like to get some input from others who might have faced such an issue, before I take a specific design approach. If you could list pros and cons of your ideas as well. That would be a bonus! Thanks.</p>

<p>UPDATE: There appear to be two equally good suggestions so far.</p>

<ol>
<li>Test the behavior of the arguments passed in, for example, write an
is_itereable method. </li>
<li>Use positional arguments and iterate over the list of items in the positional argument list.</li>
</ol>

<p>I have yet to determine which is better for my actual problem.</p>
