On Thu, 08 Nov 2012 23:44:54 -0500, Terry Reedy wrote: > On 11/8/2012 6:40 PM, Steven D'Aprano wrote: [...] >> IFoo.bar # returns a computed property > > Assuming IFoo is a class and bar is a property attribute of the class, > IFoo.bar is the property object itself, not the computed property of an > instance.
Given the context we were discussing, namely duck-typing, the examples I gave should have been understood as indications, not literal code snippets. Yes, it is true that "IFoo.bar" returns a property object, and "Foo.bar" returns an unbound method (a function in Python 3). But they are meant as illustrations, not working code samples. Much the same way that we will often talk about "list.append" when what we actually mean is the bound append method on some specific, context-dependent list instance. I am sorry that I did not make that clear and that my terminology was sloppy. But in context, duck-typing classes normally is intended to substitute an instance of one class for an instance of another class. In that case, if IFoo.bar is a property, and Foo.bar is a method, then you cannot substitute an IFoo instance for a Foo instance, or vice versa: ifoo = IFoo() ifoo.bar # returns a computed attribute foo = Foo() foo.bar() # calls the method In the general case, you cannot use ifoo.bar() where foo.bar() is expected, nor can you use foo.bar where ifoo.bar is expected. Just in case it isn't clear what I mean: Suppose the expected interface is that instance.bar is a method that takes no arguments. foo.bar() matches that interface, because bar is a method. But ifoo.bar is a property. Suppose it computes an int result. Then ifoo.bar() will try to call an int, and raise TypeError. So ifoo cannot be used in place of foo, and types IFoo and Foo are not duck-type compatible. Likewise if the expected interface is for a property or attribute, such as ifoo.bar would give. Then foo.bar returns an unbound method. Instead of getting an error there and then, you might not get an error until much later, say: integers = [1, 3, ifoo.bar, foo.bar, 42] # much later y = sum(integers) # raises TypeError because foo.bar is a method So, duck-typing classes IFoo (with bar a property) and Foo (with bar a method) will not in general work, and looks(IFoo).like(Foo) should return False. -- Steven -- http://mail.python.org/mailman/listinfo/python-list