Ian於 2017年8月18日星期五 UTC+8上午10時41分44秒寫道: > On Thu, Aug 17, 2017 at 6:03 PM, <jf...@ms4.hinet.net> wrote: > > I study some codes of a tutorial about tkinter > > (https://github.com/daleathan/widget-tour-py3) and can't figure out how it > > works. > > > > Below is the codes from its two major files: > > ---------------------------- > > # file infrastructure.py > > ... > > ... > > class callit: > > def __init__(self, function, *args ): > > self.f = function > > > > self.args = args > > > > > > def __call__(self, *ignored): > > self.f(*self.args) > > > > ... > > > > ------------------------ > > # file widget.py > > ... > > from infrastructure import * > > ... > > class DemoMainWindow(Frame): > > ... > > def _fill_textarea(self): > > ... > > # bind events > > self.text.tag_bind(tag, '<Any-Enter>', > > > > callit(self.demoenter_callback, tag) ) > > ... > > > > def demoenter_callback(self, tag): > > ... > > self.text.configure(cursor='hand2') > > ... > > > > ---------------------- > > My question is that the object which was left by > > callit(self.demoenter_callback, tag) is a callit instance, and the method > > it calls is a DemoMainWindow's method. > > How it is possible? > > Methods are just functions with a bit of magic [1] that binds the self > argument to them. > > DemoMainWindow.demoenter_callback is an unbound method object > (although in Python 3, it's just an ordinary function). When > self.demoenter_callback is evaluated, the result is not the same > unbound method object. Instead you get a different *bound* method > object, which binds the self argument to the DemoMainWindow instance. > The important point is that this binding happens when > self.demoenter_callback is evaluated, not when the method is called. > > This bound method object gets passed to the callit object, which saves > it as self.f. Later, it calls self.f() which calls the method that is > still bound to the same DemoMainWindow instance. Note that evaluating > self.f does not *rebind* the method object. Bound method objects never > get rebound; they are only created from unbound methods. > > So when self.f() is called the bound DemoMainWindow instance is used > as the value of the self argument. The fact that it was actually > called from a method of callit doesn't matter. > > [1] This magic is called the descriptor protocol, and if you want to > play with it you can use it to create your own method types! This is a > topic usually presented to intermediate-level Python programmers.
Thank you for your explaination about the bound/unbound method. I had read them in various document many times before but never pay attention to it becasue it seems didn't matter much in real world coding. >The important point is that this binding happens when >self.demoenter_callback is evaluated, not when the method is called. All I had learned about the "self" argument is that it's a hidden argument and was passed as the first argument at the time when method was called, never though it can be used to "bind" a method alone. It's completely new to me. >So when self.f() is called the bound DemoMainWindow instance is used >as the value of the self argument. The fact that it was actually >called from a method of callit doesn't matter. It seems there is a hard homework waiting for me. Any hint? --Jach -- https://mail.python.org/mailman/listinfo/python-list