Re: Inheriting dictionary

2009-08-19 Thread Hendrik van Rooyen
On Tuesday 18 August 2009 21:44:55 Pavel Panchekha wrote:
 I want a dictionary that will transparently inherit from a parent
 dictionary. So, for example:

 
 a = InheritDict({1: one, 2: two, 4: four})
 b = InheritDict({3: three, 4: foobar}, inherit_from=a)

 a[1] # one
 a[4] # four
 b[1] # one
 b[3] # three
 b[4] # foobar
 

 I've written something like this in Python already, but I'm wondering
 if something like this already exists, preferably written in C, for
 speed.

Its not inheritance, but have you looked at the update method?

-Hendrik
-- 
http://mail.python.org/mailman/listinfo/python-list


Inheriting dictionary

2009-08-18 Thread Pavel Panchekha
I want a dictionary that will transparently inherit from a parent
dictionary. So, for example:


a = InheritDict({1: one, 2: two, 4: four})
b = InheritDict({3: three, 4: foobar}, inherit_from=a)

a[1] # one
a[4] # four
b[1] # one
b[3] # three
b[4] # foobar


I've written something like this in Python already, but I'm wondering
if something like this already exists, preferably written in C, for
speed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting dictionary

2009-08-18 Thread Jan Kaliszewski

18-08-2009 o 21:44:55 Pavel Panchekha pavpanche...@gmail.com wrote:


I want a dictionary that will transparently inherit from a parent
dictionary. So, for example:


a = InheritDict({1: one, 2: two, 4: four})
b = InheritDict({3: three, 4: foobar}, inherit_from=a)

a[1] # one
a[4] # four
b[1] # one
b[3] # three
b[4] # foobar


I've written something like this in Python already, but I'm wondering
if something like this already exists, preferably written in C, for
speed.


AFAIN -- no. But you can easily implement it in Python with rather
small loss of speed...


 class InheritDict(dict):

 class NoParent(object):
 def __getitem__(self, key):
 raise KeyError('There is no %r key in the hierarchy' % key)
 def __nonzero__(self):
 return False

 noparent = NoParent()

 def __init__(self, *args, **kwargs):
 parent = kwargs.pop('inherit_from', self.noparent)
 dict.__init__(self, *args, **kwargs)
 self.parent = parent

 def __getitem__(self, key):
 try:
 return dict.__getitem__(self, key)
 except KeyError:
 return self.parent[key]


Did you do it in similar way? (just curiosity) :-)

Regards,
*j

--
Jan Kaliszewski (zuo) z...@chopin.edu.pl
--
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting dictionary

2009-08-18 Thread Nat Williams
On Tue, Aug 18, 2009 at 2:44 PM, Pavel Panchekha pavpanche...@gmail.comwrote:

 I want a dictionary that will transparently inherit from a parent
 dictionary. So, for example:

 
 a = InheritDict({1: one, 2: two, 4: four})
 b = InheritDict({3: three, 4: foobar}, inherit_from=a)

 a[1] # one
 a[4] # four
 b[1] # one
 b[3] # three
 b[4] # foobar
 

 I've written something like this in Python already, but I'm wondering
 if something like this already exists, preferably written in C, for
 speed.


Why complicate this with a custom object?  Just use regular dicts and make b
a copy of a.

a = {1: 'one', 2: 'two', 4: 'four'}
b = dict(a)
b[3] = 'three'
b[4] = 'foobar'
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting dictionary

2009-08-18 Thread Pavel Panchekha
On Aug 18, 4:23 pm, Jan Kaliszewski z...@chopin.edu.pl wrote:
 18-08-2009 o 21:44:55 Pavel Panchekha pavpanche...@gmail.com wrote:



  I want a dictionary that will transparently inherit from a parent
  dictionary. So, for example:

  
  a = InheritDict({1: one, 2: two, 4: four})
  b = InheritDict({3: three, 4: foobar}, inherit_from=a)

  a[1] # one
  a[4] # four
  b[1] # one
  b[3] # three
  b[4] # foobar
  

  I've written something like this in Python already, but I'm wondering
  if something like this already exists, preferably written in C, for
  speed.

 AFAIN -- no. But you can easily implement it in Python with rather
 small loss of speed...

   class InheritDict(dict):

       class NoParent(object):
           def __getitem__(self, key):
               raise KeyError('There is no %r key in the hierarchy' % key)
           def __nonzero__(self):
               return False

       noparent = NoParent()

       def __init__(self, *args, **kwargs):
           parent = kwargs.pop('inherit_from', self.noparent)
           dict.__init__(self, *args, **kwargs)
           self.parent = parent

       def __getitem__(self, key):
           try:
               return dict.__getitem__(self, key)
           except KeyError:
               return self.parent[key]

 Did you do it in similar way? (just curiosity) :-)

 Regards,
 *j

 --
 Jan Kaliszewski (zuo) z...@chopin.edu.pl

I implemented it in a similar way (instead of a try block, an if
block, which works a tiny bit faster; also have a multiple-parents
case, but its rare, and I could do that in Python without much loss of
speed). Pity that there's no C version; this InheritDict is kind of
the core of my application (in a very basic test, I have 329901 calls
to __getitem__).

Oh well; I'll see if I can optimize the __getattr__ function with
minor tweaking. Thanks for your help.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting dictionary

2009-08-18 Thread Jan Kaliszewski

18-08-2009 o 22:27:41 Nat Williams nat.willi...@gmail.com wrote:

On Tue, Aug 18, 2009 at 2:44 PM, Pavel Panchekha  
pavpanche...@gmail.comwrote:



I want a dictionary that will transparently inherit from a parent
dictionary. So, for example:


a = InheritDict({1: one, 2: two, 4: four})
b = InheritDict({3: three, 4: foobar}, inherit_from=a)

a[1] # one
a[4] # four
b[1] # one
b[3] # three
b[4] # foobar


I've written something like this in Python already, but I'm wondering
if something like this already exists, preferably written in C, for
speed.



Why complicate this with a custom object?  Just use regular dicts and  
make b a copy of a.


a = {1: 'one', 2: 'two', 4: 'four'}
b = dict(a)
b[3] = 'three'
b[4] = 'foobar'


Because, as I understand Pavel's intent, it has to work dynamically
(e.g. changes in 'a' reflect in behaviour of 'b'), and obviously not
only for such trivial examples like above.

*j

--
Jan Kaliszewski (zuo) z...@chopin.edu.pl
--
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting dictionary

2009-08-18 Thread Pavel Panchekha
On Aug 18, 5:11 pm, Jan Kaliszewski z...@chopin.edu.pl wrote:
 18-08-2009 o 22:27:41 Nat Williams nat.willi...@gmail.com wrote:



  On Tue, Aug 18, 2009 at 2:44 PM, Pavel Panchekha  
  pavpanche...@gmail.comwrote:

  I want a dictionary that will transparently inherit from a parent
  dictionary. So, for example:

  
  a = InheritDict({1: one, 2: two, 4: four})
  b = InheritDict({3: three, 4: foobar}, inherit_from=a)

  a[1] # one
  a[4] # four
  b[1] # one
  b[3] # three
  b[4] # foobar
  

  I've written something like this in Python already, but I'm wondering
  if something like this already exists, preferably written in C, for
  speed.

  Why complicate this with a custom object?  Just use regular dicts and  
  make b a copy of a.

  a = {1: 'one', 2: 'two', 4: 'four'}
  b = dict(a)
  b[3] = 'three'
  b[4] = 'foobar'

 Because, as I understand Pavel's intent, it has to work dynamically
 (e.g. changes in 'a' reflect in behaviour of 'b'), and obviously not
 only for such trivial examples like above.

 *j

 --
 Jan Kaliszewski (zuo) z...@chopin.edu.pl

That is indeed the point.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting dictionary

2009-08-18 Thread Simon Forman
On Tue, Aug 18, 2009 at 6:08 PM, Simon Formansajmik...@gmail.com wrote:
 On Aug 18, 3:44 pm, Pavel Panchekha pavpanche...@gmail.com wrote:
 I want a dictionary that will transparently inherit from a parent
 dictionary. So, for example:

 
 a = InheritDict({1: one, 2: two, 4: four})
 b = InheritDict({3: three, 4: foobar}, inherit_from=a)

 a[1] # one
 a[4] # four
 b[1] # one
 b[3] # three
 b[4] # foobar
 

 I've written something like this in Python already, but I'm wondering
 if something like this already exists, preferably written in C, for
 speed.


 I would consider something like the following:


 a = {1: one, 2: two, 4: four}
 b = {3: three, 4: foobar}


 from functools import partial


 def getter(first, second, key):
    try:
        return first(key)
    except KeyError:
        return second(key)


 f = partial(getter, b.__getitem__, a.__getitem__)


 # Or, if you know you'll be getting a lot of KeyErrors, you
 # can use get() instead of __getitem__().

 def getter1(first, second, key, sentinel=None):
    item = first(key, sentinel)
    if item is sentinel:
        item = second(key)
    return item

 g = partial(getter1, b.get, a.__getitem__)


 HTH,
 ~Simon
 --
 http://mail.python.org/mailman/listinfo/python-list


Since you're going for speed the overhead of using partial (which
creates a wrapper object around the getter function) can be replaced
by something like this:

def makeGetter(first, second):
def getter(key):
try:
return first(key)
except KeyError:
return second(key)
return getter


f = makeGetter(b.__getitem__, a.__getitem__)
-- 
http://mail.python.org/mailman/listinfo/python-list


Inheriting dictionary attributes and manipulate them in subclasses

2009-04-17 Thread Dominik Ruf
Hi,

I just stumbled upon the following behaviour.
 class base():
...   dic = {'1':'1', '2':'2'}
...
 class child1(base):
...   def __init__(self):
... self.dic.update({'1':'2'})
...
 class child2(base):
...   pass
...
 c1 = child1()
 c2 = child2()

 print c1.dic
{'1': '2', '2': '2'}
 print c2.dic
{'1': '2', '2': '2'}

This is not what I have excepted.
Although I know the solution to get what I want...
 class base():
...   def __init__(self):
... self.dic = {'1':'1', '2':'2'}
...
 class child1(base):
...   def __init__(self):
... base.__init__(self)
... self.dic.update({'1':'2'})
...
 class child2(base):
...   pass
...
 c1 = child1()
 c2 = child2()

 print c1.dic
{'1': '2', '2': '2'}
 print c2.dic
{'1': '1', '2': '2'}

... I wonder if there is a special reason for the behaviour in the
first example.
Shouldn't the first example behave like the second?

cheers
Dominik
--
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting dictionary attributes and manipulate them in subclasses

2009-04-17 Thread Diez B. Roggisch
Dominik Ruf wrote:

 Hi,
 
 I just stumbled upon the following behaviour.
 class base():
 ...   dic = {'1':'1', '2':'2'}
 ...
 class child1(base):
 ...   def __init__(self):
 ... self.dic.update({'1':'2'})
 ...
 class child2(base):
 ...   pass
 ...
 c1 = child1()
 c2 = child2()

 print c1.dic
 {'1': '2', '2': '2'}
 print c2.dic
 {'1': '2', '2': '2'}
 
 This is not what I have excepted.
 Although I know the solution to get what I want...
 class base():
 ...   def __init__(self):
 ... self.dic = {'1':'1', '2':'2'}
 ...
 class child1(base):
 ...   def __init__(self):
 ... base.__init__(self)
 ... self.dic.update({'1':'2'})
 ...
 class child2(base):
 ...   pass
 ...
 c1 = child1()
 c2 = child2()

 print c1.dic
 {'1': '2', '2': '2'}
 print c2.dic
 {'1': '1', '2': '2'}
 
 ... I wonder if there is a special reason for the behaviour in the
 first example.
 Shouldn't the first example behave like the second?

No, because you are creating *classvariables* when declaring things like
this:

class Foo(object):
   bar = {}

If these are mutable, changing them will change them for *all* instances.

OTOH, when assigning to an instance, this will create an
*instance*-variable. Which is what

self.some_name = some_value

does.

Diez
--
http://mail.python.org/mailman/listinfo/python-list


Variables vs attributes [was Re: Inheriting dictionary attributes and manipulate them in subclasses]

2009-04-17 Thread Steven D'Aprano
On Fri, 17 Apr 2009 17:48:55 +0200, Diez B. Roggisch wrote:

 No, because you are creating *classvariables* when declaring things like
 this:
...
 OTOH, when assigning to an instance, this will create an
 *instance*-variable. Which is what


If an integer variable is an integer, and a string variable is a string, 
and float variable is a float, and a list variable is a list (there's a 
pattern here), shouldn't a class variable be a class and an instance 
variable be an instance?

I had never noticed the usage of variable to mean attribute until a few 
months ago. What's going on? Why did people decide that confusing 
variables and attributes of variables was a good thing? What's next, 
describing dictionary keys as dictionary variables?

Sorry to pick on Diez, he's not the only one, just the latest example.


-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list