For instance, as of Python 2.7 these blocks of code are roughly equivalent (the first two are in fact identical in effect):
if isinstance(obj, collections.Sized): doSomethingWith(len(obj))
if hasattr(obj, '__len__'): doSomethingWith(len(obj))
try: doSomethingWith(len(obj)) except TypeError: pass
They all test for the same thing: that you can call len() on the object.
Not exactly: magic methods are looked up on the class, not on the instance. That’s why isintance+ABCs is the right test to use here. See http://docs.python.org/dev/reference/datamodel#special-method-names (The third block also suffers from an over-catching except clause. Put as little code as possible in the try block and use an else clause.) ABCs are not contradictory to duck typing at all:
import collections class Demo: ... def __len__(self): ... return 42 ... isinstance(Demo(), collections.Sized) True
Demo is not required to subclass Sized or register. ABCs are an optional mechanism that implements duck typing, so to speak. http://docs.python.org/dev/glossary http://docs.python.org/whatsnew/2.6#pep-3119-abstract-base-classes http://www.python.org/dev/peps/pep-3119/#abcs-vs-duck-typing Regards