|
1 | 1 | import pandas as pd
|
| 2 | +import warnings |
| 3 | +import weakref |
| 4 | + |
| 5 | + |
| 6 | +def lazy_property(fn): |
| 7 | + '''Decorator that makes a property lazy-evaluated. |
| 8 | + ''' |
| 9 | + attr_name = fn.__name__ |
| 10 | + |
| 11 | + @property |
| 12 | + def _lazy_property(self): |
| 13 | + if attr_name not in self._values.keys(): |
| 14 | + self._values[attr_name] = fn(self) |
| 15 | + return self._values[attr_name] |
| 16 | + return _lazy_property |
2 | 17 |
|
3 | 18 | class BaseObject(object):
|
4 | 19 |
|
5 | 20 | static_properties = {}
|
6 | 21 | properties = {}
|
7 | 22 |
|
8 |
| - def __init__(self, index): |
| 23 | + def __init__(self, uid, network): |
9 | 24 |
|
10 | 25 | # the object index
|
11 |
| - self.index = index |
12 |
| - # the object id |
13 |
| - self.uid = self.get_uid(index) |
14 |
| - # dictionary of static values |
15 |
| - self._static_values = {} |
| 26 | + self.uid = uid |
| 27 | + # weak reference to the network |
| 28 | + self.network = weakref.ref(network) |
| 29 | + # cache of values |
| 30 | + self._values = {} |
16 | 31 | # dictionary of calculation results, only gets
|
17 | 32 | # filled during solve() method
|
18 | 33 | self.results = {}
|
19 | 34 | # list of times
|
20 | 35 | self.times = []
|
| 36 | + # index caching |
| 37 | + self._index = None |
21 | 38 |
|
22 |
| - def get_uid(self, index): |
| 39 | + def get_index(self, uid): |
23 | 40 | raise NotImplementedError
|
24 | 41 |
|
25 |
| - def set_object_value(self, index, code, value): |
| 42 | + def set_object_value(self, code, value): |
26 | 43 | raise NotImplementedError
|
27 | 44 |
|
28 |
| - def get_object_value(self, index, code): |
| 45 | + def get_object_value(self, code): |
29 | 46 | raise NotImplementedError
|
30 | 47 |
|
31 | 48 | def reset(self):
|
32 |
| - self._static_values = {} |
| 49 | + self._values = {} |
33 | 50 | self.results = {}
|
34 | 51 | self.times = []
|
35 | 52 |
|
36 | 53 | def __str__(self):
|
37 | 54 | return "<epynet."+self.__class__.__name__ + " with id '" + self.uid + "'>"
|
38 | 55 |
|
39 | 56 | def __getattr__(self, name):
|
| 57 | + |
40 | 58 | if name in self.static_properties.keys():
|
41 |
| - return self.get_static_property(self.static_properties[name]) |
| 59 | + return self.get_property(self.static_properties[name]) |
| 60 | + |
42 | 61 | elif name in self.properties.keys():
|
| 62 | + if not self.network().solved: |
| 63 | + warnings.warn("requesting dynamic properties from an unsolved network") |
43 | 64 | if self.results == {}:
|
44 | 65 | return self.get_property(self.properties[name])
|
45 | 66 | else:
|
46 | 67 | return pd.Series(self.results[name], index=self.times)
|
47 | 68 | else:
|
48 |
| - raise AttributeError('Nonexistant Attribute',name) |
| 69 | + raise AttributeError('Nonexistant Attribute', name) |
49 | 70 |
|
50 | 71 | def __setattr__(self, name, value):
|
51 | 72 | if name in self.properties.keys():
|
52 | 73 | raise AttributeError("Illegal Assignment to Computed Value")
|
| 74 | + |
53 | 75 | if name in self.static_properties.keys():
|
54 |
| - self.set_static_property(self.static_properties[name],value) |
| 76 | + self.set_static_property(self.static_properties[name], value) |
55 | 77 | else:
|
56 | 78 | super(BaseObject, self).__setattr__(name, value)
|
57 | 79 |
|
58 | 80 | def set_static_property(self, code, value):
|
59 |
| - self._static_values[code] = value |
60 |
| - self.set_object_value(self.index, code, value) |
| 81 | + # set network as unsolved |
| 82 | + self.network().solved = False |
| 83 | + self._values[code] = value |
| 84 | + self.set_object_value(code, value) |
61 | 85 |
|
62 | 86 | def get_property(self, code):
|
63 |
| - return self.get_object_value(self.index, code) |
| 87 | + if code not in self._values.keys(): |
| 88 | + self._values[code] = self.get_object_value(code) |
| 89 | + return self._values[code] |
64 | 90 |
|
65 |
| - def get_static_property(self, code): |
66 |
| - if code not in self._static_values.keys(): |
67 |
| - self._static_values[code] = self.get_property(code) |
68 |
| - return self._static_values[code] |
|
0 commit comments