static class methods and data members

Jacek Generowicz jacek.generowicz at cern.ch
Wed Aug 25 09:57:59 CEST 2004


Warning: you probably don't want to bother reading all the stuff
between the "==========" lines

========================================================================

nzanella at cs.mun.ca (Neil Zanella) writes:

> So, unlike Python classmethods which are roughly the equivalent of
> C++ static class methods, Python staticmethods really know nothing
> about the members of the class that encloses them

And what do C++ static methods know about the class in which they are
defined? Well, they know about the class members, but have no way of
acessing any of them (other than the static ones) because there is no
this pointer. You do realize that even in C++ and Java there is a
first parameter equivalent to Python's self ... only in C++ and Java
that parameter is hidden by the surface syntax. Try looking at the
code generated by the compiler for (non-static) member functions, and
you'll see that the first parameter is the class instance ("this"),
just like in Python ... only Python doesn't lie to you about this
fact.

In C++ static methods have no "this" poniter, so they have no means of
accessing any instance attributes, because they have no knowledge of
any paricular instance. But because it is normal in C++ to access
instance attributes without explicitly specifying "this", it is
temping to be fooled that 

    struct foo {
      int i;
      static int geti() { return i; }
    };
    
    int main() {
      foo f;
      f.geti();
      return 0;
    }

might compile.

So, all you gain in C++ static methods is installing the function in
the scope of the class ..

> and act pretty much like external defs.

... just like C++ static methods.

The only practical difference between C++ static methods and Python
staticmethods is that in C++ you can access other _static_ methods (and
static data) of the class without explicitly specifying the scope in
which it is to be found:

    struct foo {
      static int i;
      static int geti() { return i; } // this will access foo::i
    };
    
    class foo:
    
        i = 3
    
        def sgeti():
            return foo.i # In Python must explicitly give the scope
        sgeti = staticmethod(sgeti)
    
        def cgeti(cls):
            return cls.i # In Python must explicitly give the scope
        cgeti = classmethod(cgeti)      

========================================================================

> So what's the advantage of a staticmethod over an external def?

It's in a namespace which the author considers to be appropriate.

Now, if you were to ask whether there is anything that can be done
with staticmethods that can's be done whith classmethods ... I'd be
hard pushed to imagine what sort of thing this could be. Anyone?

Maybe there's a minimal efficiency consideration.

> The cls first argument to a Python classmethod is analogous to the self
> first argument to __init__: when you say Class.cmethod() the Class instance
> is passed as the first parameter to the class method,

Careful with your choice of words. The class of which the instance is
an instance (yes, the actual class itself) is passed as the first
parameter to the class method.

(There is another interpretation of the words you wrote, which is more
correct, but it's harder work to interpret your words that way :-)

> and when you say instance = Class(), the instance being constructed
> is passed to __init__ as self, and when you say instance.imethod(),
> the instance is passed to imethod() as the first parameter,
> self. The parameters cls and self are barely named so by convention:
> they are not keywords in Python, unlike say the this pointer which
> is a keyword in C++.
> 
> While qualification within a class is optional in languages like C++ and
> Java, in Python you must always qualify instance variables with self within
> instance methods, and always qualify class variables with cls within Python
> class methods.

Very lucid indeed.

> Since python static methods know nothing about a class, they are equivalent
> to methods defined outside a class, except they may be called with the class
> as the first argument (for no good reason).

Some people consider organizing things in namespaces to be an
extremely good reason. (Type "import this" into your Python REPL and
read the last line that appears.)





More information about the Python-list mailing list