has a base Factory class that is meant to be subclassed and then define a default implementation to return, as well as module's to search for the class implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | class Klass1:
""" a very simple obj """
def __init__(self):
pass
def hi(self):
print 'hi'
class Factory:
""" base factory that can construct objects in a variety of ways:
* modules ['package1.subpackage',] to be searched for klass
* search global namespace
* create takes a arguement of what type of class to return
* return a default implementation - subclass must define createDefault()
"""
def __init__(self, modules=[]):
self.modules=modules
def createDefault(self):
print dir()
raise NotImplementedError
def create(self, klass=None):
import string
if klass in globals().keys():
if type(globals()[klass]).__name__=='class':
return globals()[klass]()
for module in self.modules:
try:
fromlist = []
if string.find(module, '.'): fromlist = string.split(module, '.')[:-1]
module = __import__(module, globals(), locals(), fromlist)
if hasattr(module, klass): return getattr(module, klass)()
except AttributeError: pass
return self.createDefault()
class MyFactory(Factory):
""" concrete factory that specifies:
* what modules to search for
* implements a createDefault() - which is used if class isnt found
"""
def __init__(self, modules=[]):
Factory.__init__(self,modules)
def createDefault(self):
return Klass1()
#--------much simpler one by mark lutz, http://shell.rmi.net/~lutz/talk.html
def factory(aClass, *args): # varargs tuple
return apply(aClass, args) # call aClass
class Spam:
def doit(self, message):
print message
class Person:
def __init__(self, name, job):
self.name = name
self.job = job
object1 = factory(Spam)
object2 = factory(Person, "Guido", "guru")
|
if you have classes that reside in a variety of modules but you want one place to go and get them, you can subclass the Factory class and setup your modules, as well as a default type to return if none are found.
I chose this because a friend of mine wanted this functionality verbatium (he was coming from the java world)
caveats: if you ask to create something, widget = MyFactory().create('SpecificWidgets') if the MyFactory() by default returns a GenericWidget if nothing is found will return just that. oops: also you cant specify arguements, easily fixed ;(
References: http://shell.rmi.net/~lutz/talk.html
GO4 addendum. I was hoping there would be an addendum to the go4 book one day giving Python examples. It seems as if this 'Object Oriented ...' section might serve that purpose. (Among others, of course.) Thanks for this example!
apply()
is deprecated.apply(aClass, args)
should be changed toaClass(*args)