![](https://secure.gravatar.com/avatar/463a381eaf9c0c08bc130a1bea1874ee.jpg?s=120&d=mm&r=g)
Guido van Rossum wrote:
On 2/21/06, Fuzzyman <fuzzyman@voidspace.org.uk> wrote:
I've had problems in code that needs to treat strings, lists and dictionaries differently (assigning values to a container where all three need different handling) and telling the difference but allowing duck typing is *problematic*.
Consider designing APIs that don't require you to mae that kind of distinction, if you're worried about edge cases and classifying arbitrary other objects correctly. It's totally possible to create an object that behaves like a hybrid of a string and a dict.
Understood.
If you're only interested in classifying the three specific built-ins you mention, I'd check for the presense of certain attributes: hasattr(x, "lower") -> x is a string of some kind; hasattr(x, "sort") -> x is a list; hasattr(x, "update") -> x is a dict. Also, hasattr(x, "union") -> x is a set; hasattr(x, "readline") -> x is a file.
That's duck typing!
Sure, but that requires a "dictionary like object" to define an update method, and a "list like object" to define a sort method. The mapping and sequence protocols are so loosely defined that some arbitrary decision like this has to be made. (Any object that defines "__getitem__" could follow either or both and duck typing doesn't help you unless you're prepared to make an additional requirement that is outside the loose requirements of the protocol.) I can't remember how we solved it, but I think we decided that an object would be treated as a string if it passed isinstance, and a dictionary or sequence if it has _getitem__ (but isn't a string instance or subclass). If it has update as well as __getitem__ it is a "dictionary-alike". All the best, Michael Foord
-- --Guido van Rossum (home page: http://www.python.org/~guido/)