Puzzling OO design problem

George Sakkis gsakkis at rutgers.edu
Sat Apr 9 06:49:19 EDT 2005


"Michael Spencer" <mahs at telcopartners.com> wrote:
>
> George,
>
> since you explicit allowed metaprogramming hacks :-), how about
something like
> this (not tested beyond what you see):
>
> [snipped]
>

Nice try, but ideally all boilerplate classes would rather be avoided
(at least being written explicitly). Also, it is not obvious in your
solution why and which placeholder classes have to be written (like
World2.Movable) and which do not. By the way, my current working
solution involves copying and pasting verbatim these classes :-) Below
is an abstracted example; note that the 'declaration string' of each
original class is exactly the same across all different versions after
the first (e.g. "class B(PreviousNamespace.B, A)").


#======================================================
# version_1.py

class Namespace:
    class A(object):
        def foo(self): return "version_1.foo()"
    class B(A):
        def bar(self): return "version_1.bar()"
    class C(B):
        def zen(self): return "version_1.zen()"
#======================================================
# version_2.py

from version_1 import Namespace as PreviousNamespace
class Namespace(PreviousNamespace):
    class A(PreviousNamespace.A):
        def foo(self): return "version_2.foo()"
    class B(PreviousNamespace.B, A):
        pass
    class C(PreviousNamespace.C, B):
        pass
#======================================================
# version_3.py

from version_2 import Namespace as PreviousNamespace
class Namespace(PreviousNamespace):
    class A(PreviousNamespace.A):
        pass
    class B(PreviousNamespace.B, A):
        def bar(self): return "version_3.bar()"
    class C(PreviousNamespace.C, B):
        pass

#======================================================
# test.py
# command: python test.py <#version>

def NamespaceFactory(version):
    return __import__("version_%d" % version).Namespace

print NamespaceFactory(2).B().foo() # "version_2.foo()"
print NamespaceFactory(3).C().bar() # "version_3.bar()"

import sys, inspect
namespace = NamespaceFactory(int(sys.argv[1]))
# print the __mro__ of each 'inner' class
for name,cls in inspect.getmembers(namespace,
                                   inspect.isclass):
    print cls
    for ancestor in cls.__mro__:
        print "\t", ancestor

#======================================================

George




More information about the Python-list mailing list