Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 61 lines
 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

2 comments

rbeer 20 years, 3 months ago  # | flag

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!

a 11 years, 7 months ago  # | flag

apply() is deprecated. apply(aClass, args) should be changed to aClass(*args)

Created by alan runyan on Fri, 1 Jun 2001 (PSF)
Python recipes (4591)
alan runyan's recipes (1)

Required Modules

Other Information and Tasks