Package Gnumed :: Package pycommon :: Module gmNull
[frames] | no frames]

Source Code for Module Gnumed.pycommon.gmNull

  1  """null.py 
  2   
  3  This is a sample implementation of the 'Null Object' design pattern. 
  4   
  5  Roughly, the goal with Null objects is to provide an 'intelligent' 
  6  replacement for the often used primitive data type None in Python or 
  7  Null (or Null pointers) in other languages. These are used for many 
  8  purposes including the important case where one member of some group  
  9  of otherwise similar elements is special for whatever reason. Most  
 10  often this results in conditional statements to distinguish between 
 11  ordinary elements and the primitive Null value. 
 12   
 13  Among the advantages of using Null objects are the following: 
 14   
 15    - Superfluous conditional statements can be avoided  
 16          by providing a first class object alternative for  
 17          the primitive value None. 
 18   
 19    - Code readability is improved. 
 20   
 21    - Null objects can act as a placeholder for objects  
 22          with behaviour that is not yet implemented. 
 23   
 24    - Null objects can be replaced for any other class. 
 25   
 26    - Null objects are very predictable at what they do. 
 27   
 28  To cope with the disadvantage of creating large numbers of passive  
 29  objects that do nothing but occupy memory space Null objects are  
 30  often combined with the Singleton pattern. 
 31   
 32  For more information use any internet search engine and look for  
 33  combinations of these words: Null, object, design and pattern. 
 34   
 35  Dinu C. Gherman, 
 36  August 2001 
 37   
 38  Karsten Hilbert 
 39  July 2004 
 40  """ 
 41  #============================================================== 
 42  __author__ = "Dinu C. Gherman, Karsten Hilbert" 
 43  __license__ = "GPL v2 or later (details at http://www.gnu.org)" 
 44   
 45  import logging 
 46   
 47  _log = logging.getLogger('cNull') 
 48   
 49  #============================================================== 
50 -class cNull(object):
51 """A class for implementing Null objects. 52 53 This class ignores all parameters passed when constructing or 54 calling instances and traps all attribute and method requests. 55 Instances of it always (and reliably) do 'nothing'. 56 57 The code might benefit from implementing some further special 58 Python methods depending on the context in which its instances 59 are used. Especially when comparing and coercing Null objects 60 the respective methods' implementation will depend very much 61 on the environment and, hence, these special methods are not 62 provided here. 63 """ 64 # object constructing
65 - def __init__(self, *args, **kwargs):
66 "Ignore parameters." 67 _log.debug('args: %s', args) 68 _log.debug('kwargs: %s', kwargs)
69 70 # object calling
71 - def __call__(self, *args, **kwargs):
72 "Ignore method calls." 73 _log.debug('args: %s', args) 74 _log.debug('kwargs: %s', kwargs) 75 return self
76 77 # attribute handling
78 - def __getattr__(self, attribute):
79 "Ignore attribute requests." 80 _log.debug('%s.%s', self, attribute) 81 return self
82
83 - def __setattr__(self, attribute, value):
84 "Ignore attribute setting." 85 _log.debug('%s.%s = %s', self, attribute, value) 86 return self
87
88 - def __delattr__(self, attribute):
89 "Ignore deleting attributes." 90 _log.debug('%s.%s', self, attribute) 91 return self
92 93 # item handling
94 - def __getitem__(self, item):
95 "Ignore item requests." 96 _log.debug('%s[%s]', self, item) 97 return self
98
99 - def __setitem__(self, item, value):
100 "Ignore item setting." 101 _log.debug('%s[%s] = %s', self, item, value) 102 return self
103
104 - def __delitem__(self, item):
105 "Ignore deleting items." 106 _log.debug('%s[%s]', self, item) 107 return self
108 109 # misc.
110 - def __repr__(self):
111 "Return a string representation." 112 return "<cNull instance @ %s>" % id(self)
113
114 - def __str__(self):
115 "Convert to a string and return it." 116 return '<cNull instance>'
117
118 - def __nonzero__(self):
119 _log.debug('returns 0') 120 return 0
121
122 - def __len__(self):
123 _log.debug('0') 124 return 0
125 126 #==============================================================
127 -def test():
128 "Perform some decent tests, or rather: demos." 129 130 # constructing and calling 131 132 n = cNull() 133 n = cNull('value') 134 n = cNull('value', param='value') 135 136 n() 137 n('value') 138 n('value', param='value') 139 140 # attribute handling 141 142 n.attr1 143 n.attr1.attr2 144 n.method1() 145 n.method1().method2() 146 n.method('value') 147 n.method(param='value') 148 n.method('value', param='value') 149 n.attr1.method1() 150 n.method1().attr1 151 152 n.attr1 = 'value' 153 n.attr1.attr2 = 'value' 154 155 n['1'] 156 n['2'] = '123' 157 del n['3'] 158 159 del n.attr1 160 del n.attr1.attr2.attr3 161 162 # representation and conversion to a string 163 tmp = '<cNull instance @ %s>' % id(n) 164 assert repr(n) == tmp 165 assert str(n) == '<cNull instance>' 166 167 # comparing 168 if n == 1: 169 print("Null object == 1") 170 else: 171 print("Null object != 1")
172 173 #-------------------------------------------------------------- 174 if __name__ == '__main__': 175 176 import sys 177 178 if len(sys.argv) < 2: 179 sys.exit() 180 181 if sys.argv[1] != 'test': 182 sys.exit() 183 184 test() 185