Package advene :: Package util :: Module autoproperty
[hide private]
[frames] | no frames]

Source Code for Module advene.util.autoproperty

  1  # 
  2  # This file is part of Advene. 
  3  #  
  4  # Advene is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published by 
  6  # the Free Software Foundation; either version 2 of the License, or 
  7  # (at your option) any later version. 
  8  #  
  9  # Advene is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 12  # GNU General Public License for more details. 
 13  #  
 14  # You should have received a copy of the GNU General Public License 
 15  # along with Foobar; if not, write to the Free Software 
 16  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 17  # 
 18   
 19  from sys import _getframe 
20 21 -def autoproperty(*args):
22 """Decorate a class method to create or update a property of the class. 23 24 Usage #1::: 25 @autoproperty 26 def _get_foobar(self): 27 # some code 28 29 @autoproperty 30 def set_foobar(self, val, option=0) 31 # some code 32 33 Usage #2::: 34 @autoproperty("foo", "get") 35 def bar(self): 36 # some code 37 38 @autoproperty 39 def baz(self, val): 40 # some code 41 42 In the first usage, the name of the property and the role of the method 43 (get, set or del) are inferred from the name of the method. The following 44 name patterns are recognized: role_name, _role_name, roleName, _roleName, 45 where role can be any combination of case. In the two latter cases, the 46 first letter of the name will automatically be downcased. 47 48 The docstring of the property is set to the docstring of the first method 49 used to define the property. 50 """ 51 L = len(args) 52 assert 1 <= L <= 2 53 if len(args) == 1: 54 func = args[0] 55 name, role = _infer_name_and_role(*args) 56 return _autoproperty(func, name, role) 57 else: 58 name, role = args 59 return lambda func, n=name, r=role: _autoproperty(func, n, r)
60
61 62 -def _infer_name_and_role(method):
63 n = method.__name__ 64 if n[0] == "_": n = n[1:] 65 role, name = n[:3].lower(), n[3:] 66 if name[0] == "_": 67 name = name[1:] 68 else: 69 name = name[0].lower() + name[1:] 70 assert role in ("get", "set", "del") 71 return name, role
72
73 -def _autoproperty(method, name, role):
74 ## this is the way it is supposed to be done: 75 #locals = inspect.stack()[2][0].f_locals 76 ## but that breaks (in python 2.5) so we do it the dirty way: 77 locals = _getframe(2).f_locals 78 prop = locals.get(name) 79 if prop is None: 80 kw = {"f%s" % role: method, "doc": method.__doc__} 81 else: 82 kw = {"fget": prop.fget, "fset": prop.fset, "fdel": prop.fdel, 83 "doc": prop.__doc__,} 84 kw["f%s" % role] = method 85 locals[name] = property(**kw) 86 return method
87 88 89 90 if __name__ == "__main__":
91 - class Test2(object):
92 93 _foo = None 94 _foobar = None 95 96 @autoproperty
97 - def _get_answer(self):
98 """A read only property.""" 99 return 42
100 101 @autoproperty
102 - def setFoo(self, val):
103 """A dummy property. 104 105 To get this property, use self.foo or self.getFoo(default_value). 106 """ 107 self._foo = val
108 109 @autoproperty
110 - def getFoo(self, ifNone=None):
111 r = self._foo 112 if r is None: return ifNone 113 else: return r
114 115 @autoproperty("foo_bar", "get")
116 - def GetFooBar(self):
117 return self._foobar
118 119 @autoproperty("foo_bar", "set")
120 - def SetFooBar(self, val):
121 self._foobar = val
122 123 t2 = Test2() 124