Dictionary inheritance

T

Talin

I want to make a dictionary that acts like a class, in other words,
supports inheritance: If you attempt to find a key that isn't present,
it searches a "base" dictionary, which in turn searches its base, and so on.

Now, I realize its fairly trivial to code something like this using
UserDict, but given that classes and modules already have this behavior,
is there some built-in type that already does this?

(This is for doing nested symbol tables and such.)

---

Also, on a completely different subject: Has there been much discussion
about extending the use of the 'is' keyword to do type comparisons a la
C# (e.g. "if x is list:") ?

-- Talin
 
D

Devan L

Talin said:
I want to make a dictionary that acts like a class, in other words,
supports inheritance: If you attempt to find a key that isn't present,
it searches a "base" dictionary, which in turn searches its base, and so on.

Now, I realize its fairly trivial to code something like this using
UserDict, but given that classes and modules already have this behavior,
is there some built-in type that already does this?

(This is for doing nested symbol tables and such.)

---

Also, on a completely different subject: Has there been much discussion
about extending the use of the 'is' keyword to do type comparisons a la
C# (e.g. "if x is list:") ?

-- Talin

Dictionaries aren't classes? I wasn't aware of that. Anyways, what
you're looking for, I think is a class that emulates a dictionary.
Probably you should just have some attribute that references a bigger
dictionary.

bigger_dict =
{'foo':1,'baz':2,'bar':3,'foobar':4,'foobaz':5,'foobazbar':6}
smaller_dict = {'spam':1,'ham':2,'bacon':3,'eggs':4}
smaller_dict.fallback = bigger_dict

and then the __getitem__ method might look something like

def __getitem__(self, key):
if self.has_key(key):
return self[key]
else:
return self.fallback[key]
 
J

Jordan Rastrick

Talin asked:
Also, on a completely different subject: Has there been much discussion
about extending the use of the 'is' keyword to do type comparisons a la
C# (e.g. "if x is list:") ?

-- Talin

No, is already has a specific, well defined meaning - object identity.

IDLE 1.1
a = [1,2,3]
a is list False
b = type(a)
b
b is list
True

"Extending it" to mean something entirely different to what it
currently means is a bad idea, and is also unnessecary - the builtin
function isinstance already provides the functionaliy you're looking
for:

However, use sparingly - calling isinstance unnessecarily rather than
relying on polymorphism is considered pretty unpythonic, and usually
reflects pretty poor OO design.
 
B

bruno modulix

Talin said:
I want to make a dictionary that acts like a class, in other words,
supports inheritance:

I must be missing your point here, since dict is a class and as such
support inheritence:
class MyDict(dict):pass ....
d = MyDict()
d.items() []

If you attempt to find a key that isn't present,
it searches a "base" dictionary, which in turn searches its base, and so
on.

That's not inheritence, that's contextual acquisition (Zope relies
heavily on this concept).
Now, I realize its fairly trivial to code something like this using
UserDict,

If you want to specialize dict, why use UserDict ?
but given that classes and modules already have this behavior,

Nope. Inheritence is not the solution - unless of course you want to
create a derived class for each and any of your 'nested dict' instances,
which would be a rather strange design...


Here you need composition/delegation:

class HierDict(dict):
def __init__(self, parent=None):
self._parent = parent

def __getitem__(self, name):
try:
return super(HierDict,self).__getitem__(name)
except KeyError, e:
if self._parent is None:
raise
return self._parent[name]

# to be continued according to your needs


if __name__ == "__main__":
d = HierDict(None)
d['test'] = 42
print d['test']

d2 = HierDict(d)
d2['dead'] = "parrot"

print d2['dead'] # found in d2
print d2['test'] # found in d

Also, on a completely different subject: Has there been much discussion
about extending the use of the 'is' keyword to do type comparisons a la
C# (e.g. "if x is list:") ?

I don't think there is much to discuss:

x = list
if x is list:
print "x is list"

Remember that in Python,
1/ type information pertains to objects, not to identifiers
2/ types are objects too

So, the 'is' operator being the identity operator, there is no need to
'extend' it to do type comparisons:

x = []
if type(x) is type([]):
print "x is a list"

But - even if useful in some special cases -, type comparisons in
Python are rarely necessary and in most case worst than useless:

def get_foo(a_dict):
if type(a_dict) is type({}):
foo = a_dict['foo']
else:
raise TypeError, "expected a dict, got something else"

h = HierDict()
h['foo'] = 'bar'

get_foo(h)


....definitively worst than useless...

-
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '(e-mail address removed)'.split('@')])"
 
?

=?iso-8859-1?q?Elmo_M=E4ntynen?=

I want to make a dictionary that acts like a class, in other words,
supports inheritance: If you attempt to find a key that isn't present,
it searches a "base" dictionary, which in turn searches its base, and so on.

Now, I realize its fairly trivial to code something like this using
UserDict, but given that classes and modules already have this behavior,
is there some built-in type that already does this?

(This is for doing nested symbol tables and such.)

---

You could always do:

class nestedDict(dict):
...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,311
Members
47,986
Latest member
ColbyG935

Latest Threads

Top