Alex Popescu <[EMAIL PROTECTED]> wrote: ... > - when testing from outside the class definition, the function is > already attached to the class instance and this is the reason why its > type is instancemethod
To be more precise: when you access any attribute of a class (or instance thereof), Python checks if that attribute is a descriptor (i.e. the attribute's type has a __get__ method -- there are finer distinctions based on whether it also has a __set__ method, i.e. is or isn't a "data descriptor", but they don't come into play here). A function does have in its type a __get__ method, IOW every (Python-coded) function is a descriptor (a non-data one, btw). So, when you access C.f where C is a class and f's type is Python-coded function, you get the results of calling __get__ on that f object itself. Those results are... the envelope, please!... ta-da: a newly minted method object (whose im_func is f). > - for decorators, my test is executed before the class is defined and > so at that moment the function is still a function; it will become a > methodinstance only after the class definition is closed The function object will never become a method object; it will remain a function object (and you can get at it with C.__dict__['f'] for example); but if you access that name as an attribute of C (or of an instance of C), e.g. as C.f or getattr(C, 'f'), f.__get__ will be called (and return a freshly minted method object whose im_func is f). > Is this correct or am I just fabulating here? You have roughly the right idea (as far as decorators are concerned), just a slightly skewed vision of the rapport between function objects and method objects, which I hoped I helped clarify. Here are a few toy-level examples of what I've been saying, I hope they can further help your understanding of function vs method issues: >>> def f(): pass ... >>> class C(object): pass ... >>> a=C.f Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'C' has no attribute 'f' >>> C.f = f >>> a=C.f >>> b=C.f >>> a == b True >>> a is b False >>> type(a), type(b) (<type 'instancemethod'>, <type 'instancemethod'>) >>> a.im_func, b.im_func (<function f at 0x66030>, <function f at 0x66030>) >>> a.im_func is f is b.im_func True >>> c=f.__get__(C) >>> type(c) <type 'instancemethod'> >>> c.im_func <function f at 0x66030> >>> c.im_func is C.__dict__['f'] is f True Alex -- http://mail.python.org/mailman/listinfo/python-list