staticmethod and classmethod

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Thu May 26 17:06:34 EDT 2005


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



More information about the Python-list mailing list