Bruno Desthuilliers wrote:
Thanks, that worked. But in order to make it work I had to get rid of
'self' in print_internal_date signature

Indeed. Using it that way, the print_internal_date will not be wrapped
in a method object.

Hold on! How does Python know what to wrap and what not to wrap, assuming of course programmer doesn't use @classmethod or @staticmethod? Bc self has no special significance, it's just a (strong) convention, Python can't know what's the first argument of a function supposed to be, self or regular argument, and therefore it has no way of differentiating between functions (defined in class body) designed to become methods and those that are not?

Where can I read on Python internals like this (aside from post of yours, that is)? Bc frankly skimming http://docs.python.org/reference/ didn't give me impression that a lot on the subject is there (well there's some, I found smth akin to your explanation below, although yours is way more readable)?

Thanks for explanation below -- I'm going to ask some related questions.

Mmmm... Let's try to explain the whole damn thing. It's really (and IMHO
beautifully) simple once you get it, but I agree it's a bit peculiar
when compared to most mainstream OO languages.

The first thing is that the def statement *always* yield a function
object. Always. If you don't believe it, try the following snippet:

class Foo(object):
    def bar(self):
        return "baaz"

print Foo.__dict__.keys()
print type(Foo.__dict__['bar'])

Just one thing here:

>>> Foo.bar
<unbound method Foo.bar>

Huh?! Why does it say 'unbound' method? Shouldn't that be bound method (bound to Foo, that is)?

So, why is it that type(Foo.bar) != type(Foo.__dict__['bar']) ?

>>> type(Foo.__dict__['bar'])
<type 'function'>
>>> type(Foo.bar)
<type 'instancemethod'>

instancemethod - now that's something new.


The
answer is : attribute lookup rules and the descriptor protocol.

To make a long story short, the descriptor protocol specify that, when,
during an attribute lookup, a name resolves to a class attribute AND
this attribute has a __get__ method, then this __get__ method is called
 (with either the instance or None and the class itself as arguments)

Depending, I assume, on whether this is instance call | class method call, respectively?

Hmm why does the __get__ receive class as argument on top of instance | None? After all, when having an instance, the class can always be found by instance.__class__ ? Is this for sake of class methods?

Python is science, I gather: an answer to one question bears another 10 questions.

and whatever it returns becomes the result of the attribute lookup. This
mechanism is what provides support for computed attributes.

Now the trick is that the function type do implement the descriptor
protocol. So when a function is an attribute of a class object and you
try to access it as an attribute of either the class itself or an
instance of the class, it's __get__ method is called with the instance
(or None) and the class.

Having access to itself (of course),

Quick question: how does a function access itself? Aside from rejected PEP (http://www.python.org/dev/peps/pep-3130/) I don't see the way of accessing itself outside globals() (and even then how would a function know its name -- well it shouldn't care about it really, as function object doesn't care how it's labelled, right?). Or does in "real Python" func's __get__ receive its own function (func) as an argument, like in your example implementation below?

the
instance (if there's one) and the class, it's easy for it to wrap all
this into a method object. Which is itself a callable object, that when
called mostly inject the instance as first object in the argument's list
and returns the result of calling the wrapped function object.

Aha! So that's the mechanism that makes self magically appear in an argument list! I always wondered how it worked. !!THANKS!!


My 2 cents...

Well, Bruno -- that was more like $200!

Regards,
mk

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to