-
Notifications
You must be signed in to change notification settings - Fork 1
/
property_deps.py
64 lines (54 loc) · 1.96 KB
/
property_deps.py
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
64
from abc import ABC
def del_if_there(instance, varnames):
"""Deletes all variables in varnames if they exist in instance."""
for var in varnames:
try:
delattr(instance, var)
except AttributeError:
pass
def property_deps(*args):
"""
A function decorator to generate set, get and delete methods for a
property on which others depend.
Dependent variables are deleted when the property changes or is deleted.
The decorated function will be used as getter that is executed once at
request if there is no stored value and cached until it is deleted or
set manually.
Parameters
----------
args : string list
Variable names of the depending variables.
Returns
-------
dep_property : class
A class with predifined __get__, __set__ and __delete__ methods.
Usage
-----
class some_class(some_super_class):
@property_deps('some', 'dependent', 'variables')
def my_property(self):
...
return value
"""
class baseClass:
def __init__(self, func):
self.getter = func
self.fname = '_cashed_dep_prop_' + func.__name__
def __get__(self, instance, owner):
if instance is None:
return self
if self.getter is None:
raise AttributeError("unreadable attribute")
if not hasattr(instance, self.fname):
setattr(instance, self.fname, self.getter(instance))
return getattr(instance, self.fname)
def __set__(self, instance, value):
del_if_there(instance, args)
setattr(instance, self.fname, value)
def __delete__(self, instance):
del_if_there(instance, (self.fname,) + args)
def dep_property(func):
clsdict = {'__doc__': func.__doc__}
theClass = type(func.__name__, (baseClass,), clsdict)
return theClass(func)
return dep_property