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

BASIC IDEA: Using this class as a base class, you can quickly create new classes that know what its attributes are. This is useful for simple, struct-like classes that have no methods of their own. Afterall, class syntax is more convenient than dict syntax.

Python, 63 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
62
63
"""This file contains the AutomaticClass class."""


class AutomaticClass:

    """This is a base class for simple, struct-like classes."""

    def __init__(self, **kargs):
        """Subclasses should call this after initializing any defaults.

        **kargs - Set each attribute with the given value.  Keys in kargs that
        aren't in self.__attributes__ will be ignored.  

        """
        for i in self.__attributes__:
            if kargs.has_key(i):
                setattr(self, i, kargs[i])

    def getAttributes(self):
        """Return the list of attributes that this class uses.
        
        Subclasses should extend (not override) this method to add their own
        attributes.
        
        """ 
        return []

    def __getattr__(self, attribute):
        """Handle the following attributes manually:  __attributes__.
        
        Meta, meta, meta!
        
        """
        if attribute == "__attributes__":
            return self.getAttributes()
        raise AttributeError

    def __repr__(self):
        """Return a suitable string representing of this instance."""
        attributes = []
        for i in self.__attributes__:
            try: 
                value = getattr(self, i)
            except: 
                value = "Undefined"
            attributes.append("%s=%s" % (i, value))
        return "<%s %s>" % (self.__class__.__name__, " ".join(attributes))


# This is for testing.
class _Test(AutomaticClass):
    def __init__(self, **kargs):
        self.foo = "Bar"
        AutomaticClass.__init__(self, **kargs)
    def getAttributes(self):
        return AutomaticClass.getAttributes(self) + ["foo"]


# Do some testing.
if __name__ == '__main__': 
    assert `_Test()` == "<_Test foo=Bar>"
    assert _Test().foo == "Bar"
    assert _Test(foo = "Not bar").foo == "Not bar"

There are many variations of this theme already in the cookbook.

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