[Tutor] Beginner question (variables, namespaces...) (fwd)

Kent Johnson kent37 at tds.net
Sat Apr 8 13:51:33 CEST 2006


> From: Jesse <intermezzoooh at gmail.com>
> 
> I tried redefining the "higher-order" variables as functions, but it didn't
> quite work. Here's a simplified example:
> 
> 
> var1 = 2
> 
> def timestwo(x):
>     return x*2
> 
> 
> var2 = timestwo(var1)
> print var1, var2
> var1 = 3
> print var1, var2
> 
> This results in the output:
> 2, 4
> 3,4

You still have to call the function whenever you need the value.
print var1, timestwo(var1)
var1 = 3
print var1, timestwo(var1)

> 
> ..which is not what I'm aiming for. Maybe I'll have to follow Bob's advice
> and just store all of the variable assignments in a function, and then call
> the function every time I change one of the variables (based on user input).
> I could still leave the higher-order variables as functions as per your
> advice, but that alone doesn't seem to do the trick. Unless I've missed
> something.

Danny's suggestion of using class properties is a good one, it allows 
you to automate the recalculation of the variables, and also protect 
against directly assigning one of the calculated values.

Here is a class that has two attributes, val and val2. val can be 
assigned normally. val2 is read-only and always equal to twice val.

Whenever a new value is assigned to val, the internal _recalculate() 
method is called. This is slightly more complex than needed for this 
example (_set_val()) could calculate val2 directly) but it extends 
easily to multiple settable and calculated values.

The only problem with this approach is that it is not really beginner 
material, you need some understanding of classes and properties. I don't 
know of any beginner references for properties but you could try this:
http://users.rcn.com/python/download/Descriptor.htm#properties

Anyway here is the code:

#####################
class AutoCompute(object):
     def __init__(self, val):
         self.val = val

     # Create a property named val
     # Setting val triggers recomputation
     def _set_val(self, val):
         self._val = val
         self._recompute()

     def _get_val(self):
         return self._val

     val = property(_get_val, _set_val)

     # Create a read-only property named val2
     def _get_val2(self):
         return self._val2

     val2 = property(_get_val2)


     def _recompute(self):
         self._val2 = self._val * 2

ac = AutoCompute(3)
print ac.val, ac.val2

# Assigning to ac.val changes ac.val2 also
ac.val = 4
print ac.val, ac.val2

# This raises AttributeError, val2 is read-only
ac.val2 = 5
###################################

When run, the output is
3 6
4 8
Traceback (most recent call last):
   File "F:\Tutor\ComputedProperty.py", line 33, in ?
     ac.val2 = 5
AttributeError: can't set attribute



More information about the Tutor mailing list