On 3 Nov 2005 03:19:22 -0800, "venk" <[EMAIL PROTECTED]> wrote:
>Hi, > given below is my interaction with the interpreter.... In one case, i >have created the class method using the "famous idiom"... and in the >other, i have tried to create it outside the class definition... why >isn't the latter working ? (of course, the presence of decorators is a >different issue).... >>>> class D: >... def f(cls): >... print cls >... >>>> D.f=classmethod(D.f) >>>> D.f ><bound method classobj.f of <class __main__.D at 0xb7c99f5c>> >>>> D.f() >Traceback (most recent call last): > File "<stdin>", line 1, in ? >TypeError: unbound method f() must be called with D instance as first >argument (got classobj instance instead) >>>> class D: >... def f(cls): >... print cls >... f=classmethod(f) >... >>>> D.f ><bound method classobj.f of <class __main__.D at 0xb7c9947c>> >>>> D.f() >__main__.D > I think you are on very thin ice using classmethod for old-style classes. In any case, you are not providing the same argument to classmethod in the two examples above. I'm not sure what classmethod tries to do with an unbound method, but it's not normal usage even in newstyle classes. It probably just saves the callable argument as an attribute of the classmethod instance, so the problem doesn't show until the descriptor machinery comes into play (on attribute access and calling the bound callable). >>> def showcmarg(f): print 'cmarg=%r'%f; return classmethod(f) ... >>> class D: ... def f(cls): print cls ... >>> D.f=showcmarg(D.f) cmarg=<unbound method D.f> Note that that was an unbound method as the arg, that gets stored in the descriptor >>> D.f <bound method classobj.f of <class __main__.D at 0x02EE9A1C>> >>> D.f() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: unbound method f() must be called with D instance as first argument (got classobj tance instead) That's just the callable (D unbound method) you gave it complaining that the descriptor is passing the intended cls D (a classobj) instead of an instance of D to the unbound method. >>> class D: ... def f(cls): print cls ... f = showcmarg(f) ... cmarg=<function f at 0x02EEAE2C> Note that this time that was a _function_ arg, because it was picked up as a local binding during the execution of the body of the class definition, where classmethod was called. The function will have no demands except to match its signature when the classmethod descriptor instance calls it with first arg of D. >>> D.f <bound method classobj.f of <class __main__.D at 0x02EE9A7C>> >>> D.f() __main__.D You could extract the normal (function) classmethod arg from the outside though: >>> class D: ... def f(cls): print cls ... >>> D.f=showcmarg(D.f.im_func) cmarg=<function f at 0x02EEAD84> >>> D.f <bound method classobj.f of <class __main__.D at 0x02EE9A4C>> >>> D.f() __main__.D Suggest migrating to new style classes consistently ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list