33
33
component = component.parent
36
class ObjectPath (object):
38
An ObjectPath binds the path to a certain attribute to the instance
39
of this class. It can have a relative or a absolute path, example:
44
grandparent = ObjectPath ("../..")
45
root = ObjectPath ("/", static=True)
46
a_list_count = ObjectPath("a_list.__len__()")
48
You can navigate up the hierarchy if you use the '..' fragment, this
49
assumes your object has a field named 'parent'.
51
You can also call any callable fragment using "()".
53
If you assign the 'static' keyword argument to True then the
54
value is only retrieved once.
56
def __init__ (self, path, static = False):
57
self.fullPath = path.split("/")
58
self.isAbsolute = path.startswith("/")
59
self.isStatic = static
61
def transverse (self, full_path, helper_func):
65
def __get__ (self, obj, type = None):
67
if self.isStatic and hasattr(self, "returnValue"):
68
return self.returnValue
71
obj = getRootComponent(obj)
73
for path in self.fullPath:
74
if path == "." or path == "":
79
is_callable = path.endswith("()")
81
path = path[:-len ("()")]
83
obj = getattr(obj, path)
88
self.returnValue = obj
92
class PropertyWrapper (object):
94
PropertyWrapper is usefull to wrap the getter and setter methods of a
95
variable that is not accessible through the 'property' protocol.
96
It accepts private variables as well.
98
def __init__ (self, variable, getter = None, setter = None):
99
self.variable = variable
100
self.realVariable = None
104
if self.setter is None:
107
if self.getter is None:
110
def getVariable (self, obj):
111
if self.realVariable is None:
112
if self.variable.startswith("__"):
113
self.realVariable = "_" + type(obj).__name__ + self.variable
115
self.realVariable = self.variable
116
return getattr (obj, self.realVariable)
118
def __get__ (self, obj, type = None):
119
obj = self.getVariable (obj)
120
return getattr (obj, self.getter)()
122
def __set__ (self, obj, value):
123
obj = self.getVariable (obj)
124
getattr (obj, self.setter) (value)
126
class LazyComponent (object):
128
A 'LazyComponent' is created only when it's needed. It should wrap the
129
component that you want to make lazy.
133
class Bar (Component):
136
class Foo (Component):
137
bar = LazyComponent (Bar)
139
When you create an instance of 'Foo', the 'bar' instance will only be
140
created when you access it the first time.
143
def __init__ (self, componentFactory):
144
self.componentFactory = componentFactory
146
def __get__ (self, obj, type = None):
147
if hasattr (self, "component"):
148
return self.component
150
self.component = self.componentFactory (obj)
151
return self.component
153
38
class Component (object):