
Hello, a question in the newsgroup got me thinking about the save use of the ``savespace'' flag in modules, which should be used by third party code. Think of this function as an example: def freezing(S,P): """Returns the freezing point temperature of seawater with a salinity S and at a pressure P. """ TF=(-.0575+1.710523e-3*_A.sqrt(_A.absolute(S))-2.154996e-4*S)*S-7.53e-4*P return TF This looks simple and one wants to use the savespace flag for S and P. So now the questions are rolling. What if S or P are scalars? Use asarray with the savespace flag. -> Error, this returns a copy of the array and not a reference, which is bad for array arguments. So use first asarray and then do asarray(S).savespace(1). Ok this works for the function, but we need to reset the flag at the end of the function. Also bad, what if S or P had the flag set before they entered the function? Ok I have now build a class, which actually keeps a record of these flags and has some helper methods to handle this record. The example function looks now: def freezing(S,P): SP=mkspacesaver(S,P) if not SP.isfloat(): raise ValueError, 'Arguments need to be of some float type' TF=(-.0575+1.710523e-3*_A.sqrt(_A.absolute(S))-2.154996e-4*S)*S-7.53e-4*P SP.free(); SP.clean(TF) return TF Note the test for float type, because if the user lazily entered an integer array for e.g. the pressure, the then set savespace flag would result in a very wrong answer. Although this seems to work for me, I do not know if this really presents a solution, as I actually need to put these lines into every similar function. The other way, to put the coeff. into an array has also problems, as I first need to find out of which type all arguments are and choose the highest one and it makes it more difficult to follow the coeff. in the formula. Any other suggestions, more general ways to handle argument testing? Is the savespace flag only suited for more closed environments, where one can assume more about the arguments? Class attached, __Janko class mkspacesaver: def __init__(self, *args): """Set for all arguments the savespace flag and make them to arrays. Keep track of this. At the end of the function, all flags can be reset, by a call to the method .free() """ self.refs = [] self.flags= [] for arg in args: try: arg.spacesaver() ref = arg except AttributeError: ref = afuncs.asarray(arg) self.flags.append(ref.spacesaver()) ref.savespace(1) self.refs.append(ref) def isfloat(self, index=None): """ Test if all refs have a float type, if a sequence is given for index, only the indexed refs are tested. """ if index: for i in index: if not self.refs[i].typecode() in ('f','d'): return 0 else: for i in range(len(self.refs)): if not self.refs[i].typecode() in ('f','d'): return 0 return 1 def free(self): for i in range(len(self.refs)): self.refs[i].savespace(self.flags[i]) def clean(self, *args): """Test if the arguments have the savespace flag set and set it to zero. Handle also scalars """ for arg in args: try: arg.savespace(0) except AttributeError: pass
participants (1)
-
Janko Hauser