scalar references

John Hunter jdhunter at ace.bsd.uchicago.edu
Tue Nov 18 23:28:00 EST 2003


I have some (potentially mutable) scalar values that I want to share
among many class instances.  Changes in one instance should be
reflected across the many instances.  A classic Borg is not
appropriate because I have more than one instance.

Use case: in a plotting library I have several figures.  Each figure
has a DPI parameter, possibly different between figures, which I want
to share with all the figure components (Axes, Ticks, etc...).  I want
to update the DPI in one place and have it shared across all the
relevant components of the figure.

My current approach (which works) is

class RRef:
    'A read only ref'
    def __init__(self, val):
        self._val = val

    def get(self):
        return self._val

class RWRef(RRef):
    'A readable and writable ref'
    def set(self, val):
        self._val = val

Then I can instantiate a DPI instance as

dpi = RWRef(72)

and __init__ all the figure components with it, which store 

  self.dpi = dpi

When a figure changes it's DPI via the set method, all the components
have a reference to the mutated value.

I don't really have a problem with this approach, but am wondering if
this is the best (most pythonic!) way to share a mutable scalar value
among several objects.

In addition, I want to do basic binary op arithmetic on read only
references, eg

def bintimes(x,y): return x*y
def binadd(x,y): return x+y
def binsub(x,y): return x-y

class RRef:
    'A read only ref'
    def __init__(self, val):
        self._val = val

    def get(self):
        return self._val

    def __add__(self, other):
        return BinOp(self, other, binadd)

    def __mul__(self, other):
        return BinOp(self, other, bintimes)

    def __sub__(self, other):
        return BinOp(self, other, binsub)

class BinOp(RRef):
    'A read only ref that handles binary ops of refs'
    def __init__(self, ref1, ref2, func=binadd):
        self.ref1 = ref1
        self.ref2 = ref2
        self.func = func

    def get(self):
        return self.func(self.ref1.get(), self.ref2.get())


 
Thanks for any suggestions!
John Hunter





More information about the Python-list mailing list