424,303 Members | 1,339 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,303 IT Pros & Developers. It's quick & easy.

staticmethod and classmethod

P: n/a
Hi,

Does anyone know of any examples on how (& where) to use staticmethods and
classmethods?

Thanks

Colin
Jul 19 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Think I read something about it here:

http://heather.cs.ucdavis.edu/~matloff/Python/

not sure though.

Lorenzo

Jul 19 '05 #2

P: n/a
C Gillespie wrote:
Does anyone know of any examples on how (& where) to use staticmethods and
classmethods?


My personal experience is that I almost *never* want a staticmethod.
The things that I would have written as a staticmethod in Java I simply
write as a module-level function in Python.

I do occasionally used classmethods though to build alternate
constructors. I recently had a class with a constructor that looked like:

class C(object):
def __init__(self, *args):
...

I already had code working with this constructor, but I needed to add an
optional 'index' parameter. I found the clearest way to do this was
something like:

class C(object):
def __init__(self, *args):
...
@classmethod
def indexed(cls, index, *args):
...
obj = cls(*args)
obj.index = index
...
return obj

Then the classes that needed the 'index' parameter simply use
C.indexed() as the constructor instead of C().

STeVe
Jul 19 '05 #3

P: n/a
"C Gillespie" <cs******@hotmail.com> wrote in message
news:d6**********@ucsnew1.ncl.ac.uk...
Hi,

Does anyone know of any examples on how (& where) to use staticmethods and
classmethods?
A python class method is closer to a Java static method than a python static
method.
Class methods can be useful if you want to be able to change objects in the
class, or if you want to be able to use inheritance, neither of which python
static
methods allow you to do cleanly.

Another, and rather esoteric use, is to use the class as its own instance.

I find that static methods are useful when I want to import a class from
a module, and don't want to import the module itself or a lot of bits and
pieces from the module. The class gives a place to park the method, and
also lets you use inheritance, neither of which putting it into the module
does.

John Roth
Thanks

Colin


Jul 19 '05 #4

P: n/a
C Gillespie a écrit :
Hi,

Does anyone know of any examples on how (& where) to use staticmethods and
classmethods?


Here's an example from a ldap lib (work in progress, not finished, and
all other disclaimers).

The class methods are here:

# ----------------------------------------------------------------------
# Base class for LDAP Objects
# ----------------------------------------------------------------------
class LdapObject(object):
"""
Base class for LDAP data objects.
"""

(snip)

# ------------------------------------------------------------------
def query_class(cls):
return "(objectClass=%s)" % cls.query_object_class
query_class = classmethod(query_class)

# ------------------------------------------------------------------
def query_id(cls, ldap_id):
return "(& %s (%s=%s))" % (cls.query_class(), cls.id_attribute,
ldap_id)
query_id = classmethod(query_id)

# ------------------------------------------------------------------
def query(cls, filters=None):
if filters is None:
return cls.query_class()
else:
return cls._decorate_query(filters(cls))
query = classmethod(query)

# ------------------------------------------------------------------
def _decorate_query(cls, query):
return "(& %s %s)" % (cls.query_class(), query)
_decorate_query = classmethod(_decorate_query)
class LdapContact(LdapObject):
"""
Wraps a MozillaAbPersonObsolete/OpenLDAPperson entry.
"""

# ldap objectClass(es)
object_classes =('OpenLDAPperson',
'MozillaAbPersonObsolete', )

# which one we'll use for queries
query_object_class = 'MozillaAbPersonObsolete'
id_attribute = 'uid'
sort_keys = ('displayName',)

(snip)
They are used here (LdapItemKlass is supposed to be a subclass of
LdapObject, like LdapContact above):

# ----------------------------------------------------------------------
# The LdapConnection itself.
# ----------------------------------------------------------------------
class LdapConnection(object):

(snip)

# ------------------------------------------------------------------
def list_items(self, ldapItemKlass, sort_keys=None,
filters=None):
items = [ldapItemKlass(self, entry) \
for entry in self._search( \
ldapItemKlass.query(filters, match_op) \
)]
if sort_keys is None:
sort_keys = ldapItemKlass.sort_keys
return self.sort(items, sort_keys)

# ------------------------------------------------------------------
def get_item(self, ldapItemKlass, ldap_id):
entry = self._get_item(ldapItemKlass, ldap_id)
if entry is not None:
entry = ldapItemKlass(self, entry)
return entry

(snip)
And client code may look like this (LdapContact being a subclass of
LdapObject):

cnx = LdapConnection(...).connect()
all_contacts = cnx.list_items(LdapContact)
someone = cnx.get_item(LdapContact, 'uid=someone')
Since we don't have any instance before running the query, we can't use
instance methods... Still, most of the knowledge required to build the
appropriate query belongs to the LdapContact (or whatever) class.

HTH
Bruno
Jul 19 '05 #5

P: n/a
[Bruno Desthuilliers]
C Gillespie a écrit :
Does anyone know of any examples on how (& where) to use
staticmethods and classmethods?

Here's an example from a ldap lib [...]


I recently had a use case for class methods while converting a PL/I
program to Python: a lot of global declarations, where in many cases,
procs could be regrouped around well identified subsets of globals.

The idea is to create a class for each related group of globals. The
global declarations themselves become class variables of that class, and
related procs become class methods meant to act on these class variables.

For best clarity and legibility while doing so, one should use all
lowercase class names in such cases, and use `self' instead of `cls' for
the first formal argument of class methods[1].

Then, one use these classes as if they were each the single instance
of a similar class with usual methods. If one later changes his/her
mind and wants more usual objects, and not allocated statically (!),
merely remove all classmethod declarations, capitalise the first letter
of class names, and create one instance per class into the all lowercase
name of the class. That's seemingly all.

--------------

[1] I already found out a good while ago, in many other cases unrelated
to this one, but notably in metaclasses, that `self' is often (not
always) clearer than `cls'. Classes are objects, too! :-)

--
François Pinard http://pinard.progiciels-bpi.ca
Jul 19 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.