Python's method call semantics allows you to look up a method of an object as an attribute, store it in a variable, and later invoke it like a regular function. This works similarly if you do the lookup on the class object, but when you invoke the "function" you need to pass in an instance as an argument. Consider:


class printWrapper: def __init__(self, message): self.message = message def printMe(self): print self.message

x = printWrapper("foo")
x.printMe()  # prints foo
a = x.printMe
a()                # bound method call; prints foo
b = printWrapper.printMe
b(x)               # unbound method call; prints foo


Do we have plans on how we might implement this via Parrot?

To put it another way, the expression "foo.bar()" in Python doesn't really parse as "invoke method bar on object foo", but rather as "lookup attribute bar on object foo, and call the result as a function". That's an incredibly flexible and compact semantics, and let's you do stuff like this:

class omniWrapper:
    def __init__(self, message):
            self.message = message
    def printMe(self):
            print self.message
    def __getattr__(self, attrname):
            return self.printMe

z = omniWrapper("hello")
z.printMe()         # prints hello
z.igloo()           # also prints hello
z.anythingAtAll()   # anything prints hello

That is, you can appear to be calling methods that aren't there at all. It seems odd, but makes perfect sense in light of the above description--method calls in Python are not what you might think, based on how other languages act. But that would seem to imply that Python would need a very different method call infrastructure than Perl -- a.b() in Python means something very different than $a.b() in Perl. (That of course brings up questions of how things act when Python tries to call a method on a Perl object--syntax, semantics.)

JEff



Reply via email to