On Tue, Jan 25, 2011 at 6:48 PM, Terry Reedy <tjre...@udel.edu> wrote: > This is correct! > > print(len(mo)) > TypeError: object of type 'MyObj' has no len()
That's interesting. I must admit I was not thinking about special methods in my original post, I used that example just because of Chris response. by the way, define 'correct' - if that means 'that's how this works in python', it's a tautology, not correctness :-) Instead I think this highlights an asymmetry in how python handles special methods, and makes it less ducktyped than I wanted. Consider this: class MyObject(object): @staticmethod def __len__(): return 1 mo = MyObject() print mo.__len__ print len(mo) class LenObj(object): def __len__(self): return 3 lo = LenObj() print lo.__len__ print len(lo) import types class OtherObj(object): pass oo = OtherObj() def __len__(self): return 2 oo.__len__ = types.MethodType(__len__, oo, OtherObj) print oo.__len__ print len(oo) Output: <function __len__ at 0x1004bb938> 1 <bound method LenObj.__len__ of <__main__.LenObj object at 0x1004ce510>> 3 <bound method OtherObj.__len__ of <__main__.OtherObj object at 0x1004ce590>> Traceback (most recent call last): File "pymethods.py", line 34, in <module> print len(oo) TypeError: object of type 'OtherObj' has no len() The problem is not "function attributes" - the problem is that the __len__() method must be set on the class, not on the instance. I think this is not completely clear here: http://docs.python.org/reference/datamodel.html By the way, my original post didn't take into account special methods - let's suppose they don't exist for a moment. I'd just like to check *at runtime* whether an object *any object!* respects a certain signature. *I don't want to care about the class of that object because I want true duck typing*. I mean, I should be able to pass *anything* that responds to a certain contract: @DuckType class MyInterface(object): def someMethod(self): pass def otherMethod(self, a, b): pass class SomeObj(object): @classmethod def someMethod(cls): pass @classmethod def otherMethod(cls, a, b): pass class OtherObj(object): def someMethod(self): pass def otherMethod(cls, a, b): pass class ThirdObj(object): pass oo = OtherObj() to = ThirdObj() to.someMethod = lambda: None to.otherMethod = lambda a,b: None MyInterface.maybe_implemented_by(oo) # -> True MyInterface.maybe_implemented_by(to) # -> True MyInterface.maybe_implemented_by(SomeObj) # -> True That's just what I'd like and I suppose can't be currently done with current ABC, PyProtocols or zope.interface implementations, right? -- Alan Franzoni -- contact me at public@[mysurname].eu -- http://mail.python.org/mailman/listinfo/python-list