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

If you have an instance "db", then accessing "db.Foo" automatically imports, instantiates, caches, and returns an instance of "Foo" from the "db" package.

Python, 52 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
"""This mixin supports autoloading."""

__docformat__ = "restructuredtext"


class AutoLoader:

    """This mixin supports autoloading.

    That means if you try to access an undefined attribute (e.g.
    ``self.Spam``), an aquarium.util.AquariumClass_ instance which uses this
    mixin will automatically import and instantiate the AquariumClass called
    ``Spam`` that is the same type of module as it is (e.g. a database module
    instance would try to import and instantiate ``aquarium.database.Spam``).
    This mixin is used by aquarium.database.DatabaseAssistant_, etc.  

    .. _aquarium.util.AquariumClass: 
       aquarium.util.AquariumClass.AquariumClass-class.html
    .. _aquarium.database.DatabaseAssistant: 
       aquarium.database.DatabaseAssistant.DatabaseAssistant-class.html

    """

    def __getattr__(self, attr):
        """Import, instantiate, and return the desired instance.
        
        Note, these instances will be cached in ``self._autoLoaderCache``.

        """
        if not self.__dict__.has_key("_autoLoaderCache"):
            self._autoLoaderCache = {}
        cache = self._autoLoaderCache 
        if not cache.has_key(attr):
            try:
                cache[attr] = self._ctx.iLib.aquariumFactory("%s.%s" %
                    (self.getModuleType(), attr))
            except ImportError:
                raise AttributeError("""\
%s instance has no attribute '%s', and AutoLoader failed too""" % 
                                     (self.__class__.__name__, attr))
        return cache[attr]

    def getModuleType(self):
        """Return the type of Aquarium module this instance is.
        
        Usually, I can automatically figure out what type of module you are,
        but if you need to get fancy, override this.

        """
        # If "self.__module__" yields something like "aquarium.screen.Screen",
        # the goal is to return "screen".
        return self.__module__.split(".")[1:-1]

Note that this comes from the Aquarium Web application framework, but any references to Aquarium can easily be removed.

Created by Shannon -jj Behrens on Wed, 19 Jan 2005 (PSF)
Python recipes (4591)
Shannon -jj Behrens's recipes (19)

Required Modules

  • (none specified)

Other Information and Tasks