Another idea for "class methods" recipe

James_Althoff at i2.com James_Althoff at i2.com
Fri May 25 14:54:17 EDT 2001


Here is yet another proposed recipe for "class methods" (while we wait for
the 2.2 "type/class healing").

This approach adopts the idea of using a nested class definition as
proposed in previous posts, but turns it inside out.  In this approach the
outer class is the "regular class of interest".   The inner class is a
helper for handling "class methods".  The thinking here is that you should
be able to define simple classes (that don't have "class methods") in the
"usual way".  When you want to add a "class method" , you take your
existing class and just add a little bit more to it.

This example uses the terms "StaticClass" and "static" instead of
"MetaClass" and "meta" so as to be more friendly to folks coming from
C++/Java backgrounds.  Any names, of course, could be used.

The basic idea is this:

o Define your MyClass "as usual".
o If you want to add "class methods", create a nested class inside MyClass
named "StaticClass" in which you define all of your "class methods" and
"class fields" (using the standard "class" statement).
o Immediately following, create a singleton instance of "StaticClass" named
"static" (defined as a class attribute of MyClass).

Usage:
o Invoke instance methods for MyClass instances as usual.
o Invoke a "class method" as follows:  if you have a class "MyClass" and an
instance "myInstance" and a class method "myClassMethod" then do:
    MyClass.static.myClassMethod()
    or
    myInstance.static.myClassMethod()

This approach supports both inheritance and "method override" for "class
methods".  It also avoids the problem of "method name collision" -- you can
have an "instance method" and "class method" with the same name and use
each one -- because you always use ".static" when you want to invoke a
"class method".

The example below illustrates the approach.


class MyClass:  # simple case, no "class" methods

    # no class methods

    # instance methods here as usual

    def __init__(self): pass

    def whoami(self):
        print 'MyClass.whoami:', self


print
s = MyClass()  # make an instance
s.whoami()  # instance method


class MyClass:  # if we want "class" methods

    # add static class containing "class" fields & methods

    class StaticClass:

        def __init__(self):
            self.count = 0

        def getCount(self):
            return self.count

        def incrCount(self):
            self.count += 1

        def whoami(self):
            print 'MyClass.StaticClass.whoami:', self

    static = StaticClass()  # make singleton instance

    # instance methods here as usual

    def __init__(self):
        MyClass.static.incrCount()  # count each instance creation

    def whoami(self):
        print 'MyClass.whoami:', self


print
s = MyClass()  # make an instance
s.whoami()  # instance method
MyClass.static.whoami()  # "class" method
s.static.whoami()  # works also
print 'MyClass instance count:', MyClass.static.getCount()


class MySubClass(MyClass):   # if you want a subclass

    # add static class containing "class" fields & methods

    class StaticClass(MyClass.StaticClass):  # subclass the StaticClass if
desired

        def whoami(self):
            MyClass.StaticClass.whoami(self)
            print 'MySubClass.StaticClass.whoami:', self

    static = StaticClass()  # make singleton instance

    # instance methods here as usual

    def __init__(self):
        MySubClass.static.incrCount()
        MyClass.__init__(self)

    def whoami(self):
        MyClass.whoami(self)
        print 'MySubClass.whoami:', self


print
sc = MySubClass()  # make an instance
sc.whoami()  # instance method
MySubClass.static.whoami()  # "class" method
sc.static.whoami()  # works also

sc2 = MySubClass()  # make another instance
print 'MySubClass instance count:', MySubClass.static.getCount()
print 'MyClass instance count:', MyClass.static.getCount()


>>> reload(test10)

MyClass.whoami: <test10.MyClass instance at 00820B8C>

MyClass.whoami: <test10.MyClass instance at 008206CC>
MyClass.StaticClass.whoami: <test10.StaticClass instance at 008215AC>
MyClass.StaticClass.whoami: <test10.StaticClass instance at 008215AC>
MyClass instance count: 1

MyClass.whoami: <test10.MySubClass instance at 0082117C>
MySubClass.whoami: <test10.MySubClass instance at 0082117C>
MyClass.StaticClass.whoami: <test10.StaticClass instance at 00820AEC>
MySubClass.StaticClass.whoami: <test10.StaticClass instance at 00820AEC>
MyClass.StaticClass.whoami: <test10.StaticClass instance at 00820AEC>
MySubClass.StaticClass.whoami: <test10.StaticClass instance at 00820AEC>
MySubClass instance count: 2
MyClass instance count: 3
<module 'test10' from 'c:\_dev\python20\test10.py'>

Jim





More information about the Python-list mailing list