Trying to come to grips with static methods

S

Steven D'Aprano

I've been doing a lot of reading about static methods in Python, and I'm
not exactly sure what they are useful for or why they were introduced.

Here is a typical description of them, this one from Guido:

"The new descriptor API makes it possible to add static methods and class
methods. Static methods are easy to describe: they behave pretty much like
static methods in C++ or Java."
http://www.python.org/2.2.3/descrintro.html

Great. So I have learn an entire new language to understand static
methods. Perhaps not -- hence this cry for help.

As near as I can see it, static methods are object methods that act just
like functions. Er. I always thought that object methods *were* functions,
except they had some runtime magic that passed the object itself as the
first argument.

From Guido's example:
.... def foo(x, y):
.... print "staticmethod", x, y
.... foo = staticmethod(foo)
....staticmethod 1 2

So I compare with an ordinary class function, er, method:
.... def foo(self, x, y):
.... print "method", x, y
....Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method foo() must be called with D instance as first
argument (got int instance instead)

Okay, that is to be expected. Actually, I expected an exception that I
hadn't passed enough arguments (2 arguments when foo expects 3), but in
hindsight it is obvious enough.

First point of confusion. In the above exception, foo is called an unbound
method. But type(D.foo) returns <type 'instancemethod'> even though foo is
being access through the class, not an instance. And type(D().foo) returns
the same.

Can I assume that in Python "unbound method" is just another way of saying
"a method of a class that expects to be called via an instance"?



I next tried this:
method 1 2

Clear as mud. An ordinary method called from an instance is the same as a
static method called from anywhere, provided you don't -- or rather, can't
-- try to access self from the static method.

When would you use a static method instead of an ordinary method? It has
been suggested that you might use it for functions that don't need to
access self. But that doesn't seem very convincing to me, because there is
already a perfectly good idiom for that:
.... def foo(): # returns calculated value
.... return 1
.... foo = staticmethod(foo)
.... def bar(self):
.... return 1 # just ignore the value of self
....1

What are some usage cases for using Class.StaticMethod() instead of
instance.method()? Everything I've read seems to just assume that the
benefits of static methods are so obvious that they don't need explaining.
Unfortunately, I haven't come from a background in OO and I'm easily
confused, hence this post.
 
R

Robert Kern

Steven said:
I've been doing a lot of reading about static methods in Python, and I'm
not exactly sure what they are useful for or why they were introduced.

Here is a typical description of them, this one from Guido:

"The new descriptor API makes it possible to add static methods and class
methods. Static methods are easy to describe: they behave pretty much like
static methods in C++ or Java."
http://www.python.org/2.2.3/descrintro.html

Great. So I have learn an entire new language to understand static
methods. Perhaps not -- hence this cry for help.

As near as I can see it, static methods are object methods that act just
like functions. Er. I always thought that object methods *were* functions,
except they had some runtime magic that passed the object itself as the
first argument.
[snip]

What are some usage cases for using Class.StaticMethod() instead of
instance.method()? Everything I've read seems to just assume that the
benefits of static methods are so obvious that they don't need explaining.
Unfortunately, I haven't come from a background in OO and I'm easily
confused, hence this post.

staticmethods don't see a whole lot of use in Python. They see use in
Java because everything has to be stuck in a class, even if they don't
actually require an instance of the class to work. In Python, you
usually just define a function. I think staticmethod was implemented
along with classmethod primarily for completeness than anything else.

OTOH, I do find myself using them occasionally to group such functions
appropriately. I'll be writing a utility method that doesn't actually
need an instance or the class to be passed in, so I make it a
staticmethod. It *could* just as well be a module-level function, but
sometimes it really belongs tucked in with the class. It could also be a
regular method, but then I can't call it from the outside without
actually having an instance which isn't actually needed. It could also
be a classmethod, but since it doesn't actually need any information
from the class to do its work, I find that the extra reminder of
staticmethod helps my brain understand what it's doing.

All told, I'd probably vote -0.5 on a builtin staticmethod if it came up
today.

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
R

Robert Kern

Cyril said:
(sorry, my fingers send the mail by there own ;-)

Im my opinion, class method are used to store some functionalities
(function) related to a class in the scope of the class.

For example, I often use static methods like that:

class Point:
def __init__(self, x, y):
self.x, self.y = x, y

def fromXML(xmlText):
x, y = functionToParseXMLUsingMinidomForExample(xmlText)
return Point(x, y)
fromXML = staticmethod(fromXML)

Here, it is used to define some kind of second constructor...

Note that class decorator can simplify the notation, but break the
compatility with older Python...

Huh? classmethod was introduced with staticmethod, and in fact, this use
case is exactly what classmethods are for, not staticmethods.

In [2]: class Point(object): # <-- note inheritance from object
...: def __init__(self, x, y):
...: self.x, self.y = x, y
...: def fromXML(cls, xmlText):
...: x, y = parseXML(xmlText)
...: return cls(x, y)
...: fromXML = classmethod(fromXML)
...:

In [3]: class NewPoint(Point):
...: pass
...:

In [4]: def parseXML(xmlText):
...: return 1, 4
...:

In [5]: p = NewPoint.fromXML('<point x="1" y="4"></point>')

In [6]: isinstance(p, NewPoint)
Out[6]: True

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
T

Terry Reedy

| I've been doing a lot of reading about static methods in Python,

and possibly getting over-confused by the minutia of the CPython
implementation, as well as by the misnomer. Conceptually, a 'static
method'
is a function attribute of a class that is to be used as a function and not
as a method (where 'methods', in Python, get semi-magic first parameters).
Note that function attributes of instances are also just functions, and not
methods (which sometimes fools people), as are function attributes of
modules.

| not exactly sure what they are useful for or why they were introduced.

Completeness (as RK said), occasional real usefulness, and for C++&Java
programmers. Python did fine without them.

| As near as I can see it, static methods are object methods that act just
| like functions.

Almost: class function/method, depending on your meaning of method. See
above.

|Er. I always thought that object methods *were* functions,
| except they had some runtime magic that passed the object itself as the
| first argument.

Substitute class for object and class or instance for object itself and you
have it. The runtime magic is a minor abbreviation but its major purpose
is
inheritance.

Now you can more on to something more useful like metaclasses or decorators
;-).

Terry J. Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top