Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #34729 > unrolled thread

Re: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes

Started byDave Cinege <dave@cinege.com>
First post2012-12-12 17:20 -0500
Last post2012-12-12 20:42 -0500
Articles 6 — 4 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes Dave Cinege <dave@cinege.com> - 2012-12-12 17:20 -0500
    Re: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-13 00:30 +0000
      Re: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes Chris Angelico <rosuav@gmail.com> - 2012-12-13 12:14 +1100
      Re: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes Dave Cinege <dave@cinege.com> - 2012-12-12 20:30 -0500
      Re: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes Terry Reedy <tjreedy@udel.edu> - 2012-12-12 20:36 -0500
      ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes - v20121212 Dave Cinege <dave@cinege.com> - 2012-12-12 20:42 -0500

#34729 — Re: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes

FromDave Cinege <dave@cinege.com>
Date2012-12-12 17:20 -0500
SubjectRe: ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes
Message-ID<mailman.804.1355350861.29569.python-list@python.org>
On Wednesday 12 December 2012 15:42:36 Ian Kelly wrote:

> def __getattribute__(self, name):
>     if name.startswith('__') and name.endswith('__'):
>         return super(Thesaurus, self).__getattribute__(name)
>     return self.__getitem__(name)

Ian,

Tested, and works as you advertised.

Isn't super() depreciated? I've replaced it with this:
-return super(Thesaurus, self).__getattribute__(name)
+return dict.__getattribute__(self, name)

Aside from a more palatable result in the python shell for otherwise bad 
code...does this get me anything else? Is it really worth the performance hit 
of 2 string comparisons for every getattribute call?

I also just reviewed all your original comments again:

In general: The recursion code is nothing special to me and I finally settled 
on the nested try's as something simple that 'just works good for now'. 

I think the concept of what I'm doing here is the big idea.

Should the idea of implementing what Thesaurus does in mainline python ever 
happen, those 10 lines of code will likely spark a 3 month jihad about how to 
properly do in python which up until now hasn't been something you do in 
python.

To me for i in range(len(l)) seems like simpler, faster, tighter code for this 
now. It's duly noted that enumerate() is more python and I'm an old fart that 
still thinks too much in state machine. I've add except Exception per your 
advise.

What I'd really like to hear is that someone reading was curious enough to 
convert some existing code and their joy or displeasure with the experience.

Dave

[toc] | [next] | [standalone]


#34742

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-12-13 00:30 +0000
Message-ID<50c921ae$0$29972$c3e8da3$5496439d@news.astraweb.com>
In reply to#34729
On Wed, 12 Dec 2012 17:20:53 -0500, Dave Cinege wrote:

> Isn't super() depreciated? 

Heavens no. super() is the recommended way to do inheritance, and the 
*only* way to correctly do multiple inheritance[1]. What makes you think 
that it has been deprecated?


[...]
> To me for i in range(len(l)) seems like simpler, faster, tighter code
> for this now. 

It's not. It is more complex, slower, less direct code. Python is not C, 
or Fortran, or whatever low-level language you cut your teeth on and get 
your intuitions from.

[steve@ando ~]$ python -m timeit -s "L = list('abcdefghij')" "for i in 
range(len(L)):
    c = L[i]
    pass"
1000000 loops, best of 3: 1.67 usec per loop
[steve@ando ~]$ python -m timeit -s "L = list('abcdefghij')" "for i,c in 
enumerate(L):
    pass"
1000000 loops, best of 3: 1.39 usec per loop


That's only a small performance speedup, but the real advantages are:

* the version with enumerate is much more general: it works with 
  data structures where the length is expensive to calculate, lazy 
  data streams where the length is impossible to know up front, 
  and infinite data streams;

* the version with enumerate makes the intent more clear: since we
  care about looping over the items, we should iterate over the 
  items directly, not over their indices;

* it is more readable and maintainable: both loop variables (the
  index and the item) are defined in the same place, the start of 
  the for-loop, instead of one in the header and one in the body.



> What I'd really like to hear is that someone reading was curious enough
> to convert some existing code and their joy or displeasure with the
> experience.

I don't have any code with nested dicts where this would make a 
difference. If I had such code, I would be looking to redesign it so that 
I could avoided the nested dicts, not find a palliative. The Zen of 
Python is a useful guide to general design principles:

py> import this
The Zen of Python, by Tim Peters

[...]
Flat is better than nested.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.

Your Thesaurus class violates too many of these principles for it to be 
of interest to me. Having spent a good hour or so playing around with it 
in the interactive interpreter, it is too hard for me to reason about 
what it is doing (especially since your description of what it does is 
actively misleading), and too hard to predict under what circumstances it 
will fail.

Short code is not necessarily simple code, and I find your class too 
magical and complicated to be interested in using it in production code 
as it stands now.




[1] Well, technically there's another way: one might reimplement the 
functionality of super() in your own code, and avoid using super() while 
having all the usual joys of reinventing the wheel.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#34746

FromChris Angelico <rosuav@gmail.com>
Date2012-12-13 12:14 +1100
Message-ID<mailman.814.1355361251.29569.python-list@python.org>
In reply to#34742
On Thu, Dec 13, 2012 at 11:30 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Wed, 12 Dec 2012 17:20:53 -0500, Dave Cinege wrote:
>> To me for i in range(len(l)) seems like simpler, faster, tighter code
>> for this now.
>
> * the version with enumerate makes the intent more clear: since we
>   care about looping over the items, we should iterate over the
>   items directly, not over their indices;

To add to this: Using enumerate gives the possibility (don't know if
any current interpreter takes advantage or not, but a future one
certainly could) that the enumerate() call could be optimized out.
Yes, it's theoretically possible that someone could redefine
enumerate, which would be broken by such an optimization. But all it'd
take is some kind of directive-based optimization and voila, safe
performance improvements.

Example code used:
>>> def foo(x):
	for i,val in enumerate(x):
		print("x[%d] = %s"%(i,str(val)))

>>> def foo(x):
	for i in range(len(x)):
		val=x[i]
		print("x[%d] = %s"%(i,str(val)))

A simple look at dis.dis() for the above two functions disproves the
"faster". Steven has already disproven the "simpler" and "tighter".

(I would like, though, to see a key-providing iteration as a standard
feature. Looking at dis.dis() for the above examples and also at a
simple iteration over a dictionary's .items(), I'm seeing what looks
like a lot of effort to deal with the fact that iterators return a
stream of items, rather than a stream of keys and values. But it's
probably not worth changing now.)

ChrisA

[toc] | [prev] | [next] | [standalone]


#34747

FromDave Cinege <dave@cinege.com>
Date2012-12-12 20:30 -0500
Message-ID<mailman.815.1355362208.29569.python-list@python.org>
In reply to#34742
On Wednesday 12 December 2012 20:14:08 Chris Angelico wrote:

Ok enough already, I'll use the frigging thing!

Be happy I'm at least still not coding for python 1.5.

> To add to this: Using enumerate gives the possibility (don't know if
> any current interpreter takes advantage or not, but a future one
> certainly could) that the enumerate() call could be optimized out.
> Yes, it's theoretically possible that someone could redefine
> enumerate, which would be broken by such an optimization. But all it'd
> take is some kind of directive-based optimization and voila, safe
> performance improvements.

[toc] | [prev] | [next] | [standalone]


#34748

FromTerry Reedy <tjreedy@udel.edu>
Date2012-12-12 20:36 -0500
Message-ID<mailman.816.1355362647.29569.python-list@python.org>
In reply to#34742
On 12/12/2012 7:30 PM, Steven D'Aprano wrote:
> On Wed, 12 Dec 2012 17:20:53 -0500, Dave Cinege wrote:
>
>> Isn't super() depreciated?
>
> Heavens no. super() is the recommended way to do inheritance, and the
> *only* way to correctly do multiple inheritance[1].

Indeed. Rather than super() being deprecated, it was made easier to use 
in 3.x by being special cased during compilation. Notice the difference 
of signatures:

2.7: super(type[, object-or-type])
3.3: super([type[, object-or-type]])

"The zero argument form only works inside a class definition, as the 
compiler fills in the necessary details to correctly retrieve the class 
being defined, as well as accessing the current instance for ordinary 
methods."

> [1] Well, technically there's another way: one might reimplement the
> functionality of super() in your own code, and avoid using super() while
> having all the usual joys of reinventing the wheel.

This deeper integration means that it could not be completely 
reimplemented in Python ;-).

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#34749 — ANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes - v20121212

FromDave Cinege <dave@cinege.com>
Date2012-12-12 20:42 -0500
SubjectANNOUNCE: Thesaurus - a recursive dictionary subclass using attributes - v20121212
Message-ID<mailman.817.1355362956.29569.python-list@python.org>
In reply to#34742

[Multipart message — attachments visible in raw view] — view raw

Version 20121212

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web