On 2010-11-30, at 17:52 , Dima Tisnek wrote:
Ahem, what happened to duck typing? Nothing.
To me, the whole isinstance(datum, type) appears no more elegant than the Java way (class implements this interface, implements that interface, ad infinitum) You're wrong. In fact, it could hardly be more different than what Java does. Python's ABCs are simply used to name ducks (and maybe one day tools can use them to implement a restricted structural static type system for python, who knows).
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. They don't test anything about your type hierarchy or which interfaces you inherit, which would be the only thing doable in Java (barring abuses of reflection). `collections.Sized` is simply a name for "I can call len() on this object".
anyhow it's not pythonic. The inclusion of abcs in Python strongly seems to disagree with that statement.
how to test that object can do .lower(), .startswith(), .decode(), but not all methods of str/unicode? Depends if you can give a name to that structure. That's what ABCs do when they're used as "instance testers" (they can also be used as mixins which is very nice in that you don't have to reimplement every single method of `set` yourself to create a new and separate set type): they check that the instance provided has the right structure. Not that it inherits from the right class or implement the right methods. If you check what `isinstance(obj, collections.Iterator)` does for instance, it aliases to this:
hasattr(obj, "next") and hasattr(obj, "__iter__") the former looks much more readable than the latter, doesn't it? And they mean the exact same thing. It's not like ABCs remove your ability to EAFP