Connecting Tech Pros Worldwide Help | Site Map

staticmethod and classmethod

C Gillespie
Guest
 
Posts: n/a
#1: Jul 19 '05
Hi,

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

Thanks

Colin


lbolognini@gmail.com
Guest
 
Posts: n/a
#2: Jul 19 '05

re: staticmethod and classmethod


Think I read something about it here:

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

not sure though.

Lorenzo

Steven Bethard
Guest
 
Posts: n/a
#3: Jul 19 '05

re: staticmethod and classmethod


C Gillespie wrote:[color=blue]
> Does anyone know of any examples on how (& where) to use staticmethods and
> classmethods?[/color]

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
John Roth
Guest
 
Posts: n/a
#4: Jul 19 '05

re: staticmethod and classmethod


"C Gillespie" <csgcsg39@hotmail.com> wrote in message
news:d6v2s5$blp$1@ucsnew1.ncl.ac.uk...[color=blue]
> Hi,
>
> Does anyone know of any examples on how (& where) to use staticmethods and
> classmethods?[/color]

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[color=blue]
>
> Thanks
>
> Colin
>
>[/color]

Bruno Desthuilliers
Guest
 
Posts: n/a
#5: Jul 19 '05

re: staticmethod and classmethod


C Gillespie a écrit :[color=blue]
> Hi,
>
> Does anyone know of any examples on how (& where) to use staticmethods and
> classmethods?
>[/color]

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
François Pinard
Guest
 
Posts: n/a
#6: Jul 19 '05

re: staticmethod and classmethod


[Bruno Desthuilliers][color=blue]
> C Gillespie a écrit :[/color]
[color=blue][color=green]
> > Does anyone know of any examples on how (& where) to use
> > staticmethods and classmethods?[/color][/color]
[color=blue]
> Here's an example from a ldap lib [...][/color]

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
Closed Thread