No-brainer? Dictionary keys to variable name?

Donnal Walter donnal at donnal.net
Sun Aug 4 16:43:20 CEST 2002


Christopher Myers <chris.myers at ingenta.com> wrote in message news:<3D4AEA18.7AABBC3C at ingenta.com>...
> I have decided to do the following, and it works fine for me:
> 
> I kept the function definition with all the keyword arguments, with
> defaults, and I call the function using 
> 
> function(**dict)
> 
> and it works nicely, and as I wanted.

On a similar note, I had wanted to define a base class for mutable
objects (which I call Cells) that know how to calculate their own
values from the values of other cells. The user should be able to
define the calculation something like this:

class Flow(Cell):
    def Calculate(self, vol=Cell(), time=Cell()):
        self.Set(vol.Get() / time.Get())

The user should be also able to specify which cells are to be used for
this calculation at compile time (instantiation/initialization):

class MyDataObject(object):
    def __init__(self):
        self.vol1 = Cell()
        self.time1 = Cell()
        self.flow1 = Flow(self.vol1, self.time1)
        self.vol2 = Cell()
        self.time2 = Cell()
        self.flow2 = Flow(time=self.time2, vol=self.vol2)

Notice that self.flow1 specifies the independent variables as
positional arguments, while self.flow2 specifies them as keyword
arguments (and note that it doesn't matter that they are out of
position).

Of course it is easy enough to collect and store either type of
arguments:

class Cell(object):
    def __init__(self, *args, **kwargs):
        self.__args = args
        self.__kwargs = kwargs

But until I read this thread I couldn't figure out how to pass the
positional argument list or the keyword argument dict to the method
Calculate(...). The solutions given above work if I add another method
Update() to the base class:

    def Update(self):
        self.Calculate(*self.__args, **self.__kwargs)

Now self.flow1.Update() and self.flow2.Update() cause these two
dependent cells to calculate their values from the appropriate
independent cells. Here is the final version of the base class:

class Cell(object):
    def __init__(self, *args, **kwargs):
        self.__value = None
        self.__args = args
        self.__kwargs = kwargs
        if self.__kwargs or self.__args:
            self.Update()
        else:
            self.Set(0)

    def Set(self, value):
        if value != self.__value:
            self.__value = value
            # do more stuff here

    def Get(self):
        return self.__value

    def Update(self):
        self.Calculate(*self.__args, **self.__kwargs)

    def Calculate(self): pass   # abstract method for derived classes

(Actually, this is a simplified version. In the final version, I add
support for the observable/observer pattern and automatic update of
dependent cells when a dependent cell changes its value.)

Donnal Walter
Arkansas Children's Hospital



More information about the Python-list mailing list