views:

66

answers:

2

I have a Python class C which should have two pseudo-dicts a and b. The term pseudo-dicts means that the dictionaries don't actually exist and that they are “recomputed” each time a key is accessed.

In pseudocode this would look like this:

class C:
    def a.__getitem__(self, key):
        return 'a'
    def b.__getitem__(self, key):
        return 'b'

>>> c = C()
>>> c.a['foo']
'a'
>>> c.b['bar']
'b'

I could implement a class for a and b, but since both have just a few short methods, I wonder whether there is a more elegant and compact way to do this.

+1  A: 

Why not just define your own class?

class PseudoDict(object):
    def __init__(self, c):
        self.c = c

    def __getitem__(self, key):
        return self.c.somethingmagical()

class C(object):
    def __init__(self):
        self.a = PseudoDict(self)
        self.b = PseudoDict(self)

c = C()
print c.a['foo']
print c.b['bar']

I'm not sure where the values for these 'pseudo-dicts' are coming from, so you'll have to update the __getitem__ method.

carl
The values from the pseudo-dicts are coming from `C`, so this approach would `PseudoDict` require to have access to “private” variables of `C`.
ott
@ott, I'm still not sure where the values are coming from, but I updated the example.
carl
@ott, you could also pass the function to be used to retrieve the value from `C` to the `PseudoDict` constructor, so that `a` and `b` are actually capable of providing different values.
Daniel Beck
If PseudoDict is using "private" variables of C (ie tightly coupled) it's probably more appropriate to define PseudoDict inside the scope of C to reflect the tight coupling
gnibbler
You might want to use a weak reference to `C`, to avoid reference cycles.
jchl
+1  A: 

Like this?

from collections import defaultdict
class C:
    a = defaultdict(lambda:'a')
    b = defaultdict(lambda:'b')

c=C()
print c.a['foo']
print c.b['bar']

Or maybe like this for real calculation functions?

from collections import defaultdict

class C:
    def __init__(self):
        self.a = defaultdict(self.geta)
        self.b = defaultdict(self.getb)
    def geta(self):
        return 'a'
    def getb(self):
        return 'b'

c=C()
print c.a['foo']
print c.b['bar']
Tony Veijalainen
They aren't supposed to return constants. Furthermore they should support multiple keys.
ott
Could you give real example of the use and why the pseudodict is needed?
Tony Veijalainen