On Nov 13, 10:55 pm, Steven D'Aprano <[EMAIL PROTECTED] cybersource.com.au> wrote:
> Take this example: > > def foo(alist): > alist.sort() > alist.append(5) > > The argument can be any object with sort and append methods (assumed to > act in place). But what happens if you pass it an object with a sort > method but no append? The exception doesn't occur until *after* the > object is sorted, which leaves it in an inconsistent state. This can be > undesirable: you might need the function foo to be atomic, either the > entire function succeeds, or none of it. In this example atomicity is not guaranteed even if alist is a builtin list (if it contains a complex number or other unorderable object), let alone if not isistance(alist, list). It gets worse: false positives are less likely for full-spelled methods with well-known names such as "sort" and "append" (i.e. if hasattr(alist, 'append'), alist.append *probably* does what you think it does), but good luck with that when testing for __getitem__, __iter__ for more than one pass, __call__, and other special methods with ambiguous or undefined semantics. Let's face it, duck typing is great for small to medium complexity projects but it doesn't scale without additional support in the form of ABCs/interfaces, explicit type checking (at compile and/or run time), design by contract, etc. It must not be a coincidence that both Zope and Twisted had to come up with interfaces to manage their massive (for Python at least) complexity. George -- http://mail.python.org/mailman/listinfo/python-list