Confused with classmethods

Diez B. Roggisch deetsNOSPAM at web.de
Fri Mar 11 08:24:52 EST 2005


> Not necessarily:
> 
> def foo(cls):
>      print cls
> f=classmethod(foo)
> 
> class A: pass
> 
> A.f = f
> a=A()
> a.f()

Ahhh, yes, I see the minor difference - I didn't recognize it before.

> 
> This works.  Anyway, the confusion starts from the documentation of
> classmethod().  Since classmethod is a *function* of builtins we can
> invoke it as such from wherever we want.  

Sure. AFAIK it is actually a descriptor. From what I understand, when
calling a descriptor on an instance it will invoke it's __get__ method and
pass the instance as first argument.  So classmethod just gets the
__class__ from that argument and passes it to its callable together with
the rest of the arguments.

But this magic seems only to work if the descriptor has been fetched from a
classes __dict__, not the instance __dict__. Hmm. Nice.

> Moreover the documentation 
> sais that if the first argument is an instance, its class will be
> used for the classmethod.  OTOH, "class scope" is not a real thing in
> python.  It is just some code which is executed and then we get its
> locals and use it on Class(localsDict, BasesTuple, ClassName) to make
> a new class, it seems.  So we can create a classmethod in any scope
> and then just attach it to a class's dictionary.

I'd still call the code executed inside a class statement block a "scope" -
for example in a def-statement the scope is the current frame of execution,
so 

def foo():
   bar = "baz"

makes the bar part of the frames local variables. Scopes just exchange or
stack the  dicts for name lookup.

-- 
Regards,

Diez B. Roggisch



More information about the Python-list mailing list