Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #34729 > unrolled thread
| Started by | Dave Cinege <dave@cinege.com> |
|---|---|
| First post | 2012-12-12 17:20 -0500 |
| Last post | 2012-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.
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
| From | Dave Cinege <dave@cinege.com> |
|---|---|
| Date | 2012-12-12 17:20 -0500 |
| Subject | Re: 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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Dave Cinege <dave@cinege.com> |
|---|---|
| Date | 2012-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]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-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]
| From | Dave Cinege <dave@cinege.com> |
|---|---|
| Date | 2012-12-12 20:42 -0500 |
| Subject | ANNOUNCE: 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