Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Python dumps core with this.. how come?

1 view
Skip to first unread message

Roey Katz

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to

I'm running Red Hat Linux 5.2, kernel 2.0.36 with 128 MB of memory.
"Python 1.5.2 (#2, Jun 13 1999, 17:00:15) [GCC 2.7.2.3] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam"

When I import this module, the interpreter segfaults.
Thiis module provides a little guard mechanism to keep track of
changes to registered variables. The error occurs when you ty to
instantiate class 'basic_monitor'. Also, I have another question (very
old, and I can't find this in the FAQ): I want to explicitly take a
reference to an integer. Take __setattr__() for example: is origval
a reference or merely a copy of self.res[ val ]? that is, do I change
self.res[ val ] by changing origval? Will Python2 implement some
sort of epxlicit referencing operator so that these situations won't
seem as confusing?
Whatever happened to
var := val
for assignment, and
var2 = &var1
for referencing? The addition of these explicit facilities would
greatly relieve a large portion of my Python problems (is there some
sort of rule-list to follow to figure out when exactly Python will
take a reference (like assigning from an object) or a literal value
(int's)? ).

Thanks :)
Roey
===================================================


"""module baseMonitor"


class resource_entry:
def __init__( self, minval, maxval, min_callback, max_callback ):
self.minval = minval
self.maxval = maxval
self.min_callback = min_callback
self.max_callback = max_callback


class basic_monitor:

def __init__( self ):
self.xres = [] # list of resource entries

def track( self, name, minval, maxval,
min_callback, max_callback ):

self.res[ name ] = resource_entry( minval, maxval,
min_callback, max_callback )


def __getattr__( self, name ):
return self.res[ name ]

def __setattr__( self, name, val ):
origval = self.res[ name ]
if minval < val < maxval:
origval = val
elif val < minval:
origval.min_callback()
elif val > maxval:
origval.max_callback()


if __name__=="__main__":
m = basic_monitor()

Brad Howes

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to
ka...@glue.umd.edu (Roey Katz) writes:

<snip>

> When I import this module, the interpreter segfaults.

<snip>

> class basic_monitor:
>
> def __init__( self ):
> self.xres = [] # list of resource entries

This is innocuous line is the start of your troubles. Below you declare
__setattr__ which tells Python you want to handle all attributes settings for
this instance. So...

> def __setattr__( self, name, val ):
> origval = self.res[ name ]

But now you've asked for the attribute 'res' which has yet to be defined for
this instance. You've declared __getattr__ which tells Python to call it when
an attribute is not available (which it isn't yet)

> def __getattr__( self, name ):
> return self.res[ name ]

Here, we try to get the same attribute Python failed to get. So, Python calls
your hook again, and again, and again, until lack of stack tells Python to stop
this silliness and to go get a beer.

Since you've defined both hooks, you're going to have to work with the
instance's attribute dictionary __dict__

dict = self.__dict__

and do your attribute setting using the usual dictionary methods (you could
also declare "class" attributes with default values) That should keep Python up
a bit longer.

Brad

--
Brad Howes C C++ HTML Java Python
Waltham, MA Programmer

"Were people this stupid before TV?" -- _White Noise_ by Don DeLillo

Fredrik Lundh

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to ka...@glue.umd.edu
Roey Katz <ka...@glue.umd.edu> wrote:
> When I import this module, the interpreter segfaults.
>
> Thiis module provides a little guard mechanism to keep track of
> changes to registered variables. The error occurs when you ty to
> instantiate class 'basic_monitor'.

looks like a recursive call in getattr (if "res" is
not already available in the instance, it asks
__getattr__ to look it up).

make sure to define "res" in the __init__ function,
and everything will work as you expected.

> Also, I have another question (very old, and I can't find this in the
> FAQ): I want to explicitly take a reference to an integer.

1. reset your brain ;-)
2. variables are named references, not small boxes
that hold data values
3. *all* variables in python are references. there
is no other thing.
4. integers cannot be modified in place.

in other words, Python always copies references, but
you cannot modify objects in place unless their inter-
face allows you to (numbers, tuples and strings cannot
be modified in place, while lists and dictionaries can --
the only difference is that the former doesn't provide
any methods that let you modify them...)

> is there some sort of rule-list to follow to figure out when
> exactly Python will take a reference (like assigning from an
> object) or a literal value (int's)?

yes, and it's very simple:

Q: when does Python copy a reference and not a value?
A: always!

related FAQ entries:
http://www.python.org/doc/FAQ.html#4.35
http://www.python.org/doc/FAQ.html#4.38
http://www.python.org/doc/FAQ.html#4.50
http://www.python.org/doc/FAQ.html#4.89
and probably a few more.

</F>

<!-- (the eff-bot guide to) the standard python library:
http://www.pythonware.com/people/fredrik/librarybook.htm
&mdash; see it live on the python conference! &smiley; -->

Roey Katz

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to
On Sat, 22 Jan 2000 09:50:58 +0100, "Fredrik Lundh"
<fre...@pythonware.com> wrote:

>looks like a recursive call in getattr (if "res" is
>not already available in the instance, it asks
>__getattr__ to look it up).

Thanks, I got it right after I posted :)
this brings up another concern. Given
the following definition:

class A:

def __getattr__( self, name ):

return -1

def __setattr__( self, name, val ):

self.__dict__[ name ] = val

I see that self.__dict__ must be a special variable
in that setting it somehow avoids a recursive call
to __setattr__()?

>> Also, I have another question (very old, and I can't find this in the
>> FAQ): I want to explicitly take a reference to an integer.
>
>1. reset your brain ;-)
>2. variables are named references, not small boxes
> that hold data values
>3. *all* variables in python are references. there
> is no other thing.
>4. integers cannot be modified in place.

Ok, OK: this is what I always get when I ask this question,
but then why does this happen:

>>> a = 3
>>> b = a
>>> b
3
>>> a = 5
>>> b
3

I mean, what happens if I have a complicated path
to a variable and I want to alias it:

alias = long_name.hard_to_type[ 1 ].integer_value

# arbitrary calculations that would be
# torturous with any label longer than 'alias'
if alias > someValue:
result = (alias * 5 ) / (alias + 4 )
else:
result = (alias * 3 ) / (alias + 2 )

>in other words, Python always copies references, but
>you cannot modify objects in place unless their inter-
>face allows you to (numbers, tuples and strings cannot
>be modified in place, while lists and dictionaries can --
>the only difference is that the former doesn't provide
>any methods that let you modify them...)

so where does this definition fit in the context I mentioned?
I understand that if I have a function and pass to it a parameter,
I can modify it in-place (although that I cannot modify numbers,
strings or tuples in-place seems to me inconsistent).
So for example, these are roughly equivalent:

void setValue( int& x ) { x = 3 } // C++
void setValue( int *x ) { *x = 3 } // C
def setValue( x ): x = 3 # Python

whoops, we cannot modfiy integers in-place, how invonvenient. Though
we could always wrap them in a class and overload its = operator
(wait! no = operator to overload! double inconvenience!) or have a
specially defined set() function:

class A:
def set( self, val ):
self.value = val

def setValue( a ):
a.setValue( 5 )

so that works, but do you see how it is sort of polluting? I mean, the
interface is not so simple anymore.

>Q: when does Python copy a reference and not a value?
>A: always!

ayeee! missed it! terribly sorry :)


ok, here's a third question, and it builds on the above inquiry
regarding a lack of an assignment operator. What happens when I want
to do convert this for loop:

for i,j in dest, src:
dest[ i ] = src[ j ]

into a fast map() expression:

map( dest.assign_operator, src )

like I mentioned -- there is no assignment operator to overload!
the trouble here is that there may be more situations in which
I cannot use filter() to narrow down the list to only the elements
that I want and then copy it into another list with src.copy().

Thanks!
Roey

Fredrik Lundh

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to ka...@glue.umd.edu
Roey Katz <ka...@glue.umd.edu> wrote:
> >> Also, I have another question (very old, and I can't find this in the
> >> FAQ): I want to explicitly take a reference to an integer.
> >
> >1. reset your brain ;-)
> >2. variables are named references, not small boxes
> > that hold data values
> >3. *all* variables in python are references. there
> > is no other thing.
> >4. integers cannot be modified in place.
>
> Ok, OK: this is what I always get when I ask this question,
> but then why does this happen:
>
> >>> a = 3
> >>> b = a
> >>> b
> 3
> >>> a = 5
> >>> b
> 3

you missed points (1) and (2) in my mail ;-)

to make it clearer, here's one more:

5. simple assignments don't copy any data,
they rebind the name

(here, a simple assignment is an assignment
of the form "name = expression". more com-
licated assignments like "name[index] = value"
are syntactic sugar; they map to method calls
that modify the object referred to by "name")

so the second assignment associates the
name "a" with *another* integer value.

it does *not* modify the contents of the
small box that hold the data value...

any name (like "b") that refers to the
old value still refers to the old value.

got it?

> although that I cannot modify numbers, strings
> or tuples in-place seems to me inconsistent

why on earth do you need to change the value
of "1"?

(if that question doesn't make sense, reset your
brain and start over from (1) ;-)

(sorry, no time to elaborate further. gotta run.
see you all at the conference!)

Michael Hudson

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to
Pre-point: Python is Python, not some other programming language you
may have used in the past. When you are writing Python code, try to
write Python, not brutally translate C (or whatever) to Python. This
can be tricky, depending on how ingrained your habits are, but it's
the only path to happiness.

ka...@glue.umd.edu (Roey Katz) writes:

> On Sat, 22 Jan 2000 09:50:58 +0100, "Fredrik Lundh"
> <fre...@pythonware.com> wrote:
>
> >looks like a recursive call in getattr (if "res" is
> >not already available in the instance, it asks
> >__getattr__ to look it up).
>
> Thanks, I got it right after I posted :)
> this brings up another concern. Given
> the following definition:
>
> class A:
>
> def __getattr__( self, name ):
> return -1
> def __setattr__( self, name, val ):
> self.__dict__[ name ] = val
>
> I see that self.__dict__ must be a special variable
> in that setting it somehow avoids a recursive call
> to __setattr__()?

Yup. Look in Objects/classobject.c around about line 580 if you want
the gory details.

>
>
> >> Also, I have another question (very old, and I can't find this in the
> >> FAQ): I want to explicitly take a reference to an integer.
> >
> >1. reset your brain ;-)

This is the best advice in /F's post.

> >2. variables are named references, not small boxes
> > that hold data values
> >3. *all* variables in python are references. there
> > is no other thing.
> >4. integers cannot be modified in place.
>
> Ok, OK: this is what I always get when I ask this question,
> but then why does this happen:
>
> >>> a = 3
> >>> b = a
> >>> b
> 3
> >>> a = 5
> >>> b
> 3

Lets rewrite your example a bit:

d = {}
d['a'] = 3
d['b'] = d['a']
d['b'] ==> 3
d['a'] = 5
d['b'] ==> 3

That's more-or-less what's going on under the hood. The line 'a=5'
changes "what 'a' points at" and does *not* change "what" 'a' points
at. Is this helping?

> I mean, what happens if I have a complicated path
> to a variable and I want to alias it:
>
> alias = long_name.hard_to_type[ 1 ].integer_value
>
> # arbitrary calculations that would be
> # torturous with any label longer than 'alias'
> if alias > someValue:
> result = (alias * 5 ) / (alias + 4 )
> else:
> result = (alias * 3 ) / (alias + 2 )

This is all fine so long as you don't need to change the value
referred to. You can alias up to the last '.', eg:

s = package.module.sub_module.object[2].sub_field
s.attr = s.attr + 1

None of the above are as simple as

def getValue(): return 3

I dislike this style you use in C, too. As Python has reference
semantics, you don't have the C gotcha of trying to return a four
megabyte structure on the stack, and a sensible exception system means
you don't need to have *every* function return a HRESULT <wink>.

To return more than one result, return a tuple. Or pass in some
instance object that more expresses what you are trying to acheive.

> >Q: when does Python copy a reference and not a value?
> >A: always!
> ayeee! missed it! terribly sorry :)
>
>
> ok, here's a third question, and it builds on the above inquiry
> regarding a lack of an assignment operator. What happens when I want
> to do convert this for loop:
>
> for i,j in dest, src:
> dest[ i ] = src[ j ]

I don't think you mean this. This is (loosely) equivalent to

dest[ dest[0] ] = src[ dest[1] ]
dest[ dest[0] ] = src[ dest[1] ]

I think you mean

for i in range(len(src)):
dest[i] = src[i]

> into a fast map() expression:
>
> map( dest.assign_operator, src )

map(operator.__setitem__,[dest]*len(src),range(len(src)),src)

should do what you want;

map(dest.append,src)

or

map(dest.__setitem__,range(len(src)),src)

*may* do what you what, depending on circumtances.

Bizarrely,

filter(dest.append,src)

is probably more memory efficient (the map form conses up a list of
return values, but as append always returns None - which is false -
filter `rejects' every element) - but if you write code like this, you
deserve to lose.

> like I mentioned -- there is no assignment operator to overload!
> the trouble here is that there may be more situations in which
> I cannot use filter() to narrow down the list to only the elements
> that I want and then copy it into another list with src.copy().

In general, don't be too obsessive about turning loops into maps and
filters. You're probably not saving as much as you think. for is far
clearer, and if every cycle is *that* precious, why Python?

(maphash #'(lambda (k v) (setf (gethash dest k) v)) src)-ly y'rs
Michael

Neil Schemenauer

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to
Roey Katz <ka...@glue.umd.edu> wrote:

>...why does this happen:


>
> >>> a = 3
> >>> b = a
> >>> b
> 3
> >>> a = 5
> >>> b
> 3

Let me try some ASCII art:

a = 3
b = a

gives you this (conceptually):

+---+ +---+
| a |------>| 3 |
+---+ / +---+
/
+---+ /
| b |-/
+---+

When you do:

a = 5

now you have this:

+---+
->| 5 |
/ +---+
/
+---+ / +---+
| a |-/ ->| 3 |
+---+ / +---+
/
+---+ /
| b |-/
+---+

Variables do not contain values. They refer to them. In Python
everything is a reference. Try using the id() function to see
what are the individual objects.

>I mean, what happens if I have a complicated path
>to a variable and I want to alias it:
>
> alias = long_name.hard_to_type[ 1 ].integer_value
>
> # arbitrary calculations that would be
> # torturous with any label longer than 'alias'
> if alias > someValue:
> result = (alias * 5 ) / (alias + 4 )
> else:
> result = (alias * 3 ) / (alias + 2 )

In Python you need one more step:

long_name.hard_to_type[ 1 ].integer_value = alias

When there is a tradoff between convience and explicitness,
Python chooses explicitness. If you have a name that ugly you
are probably doing something wrong already.



>I understand that if I have a function and pass to it a parameter,
>I can modify it in-place (although that I cannot modify numbers,
>strings or tuples in-place seems to me inconsistent).

You can modify objects if they are "mutable". Integers, strings
and tuples are "immutable" for a reason. Just use Python some
more and think about why it is the way it is. The FAQ has some
more details if you are interested.

>So for example, these are roughly equivalent:
>
> void setValue( int& x ) { x = 3 } // C++
> void setValue( int *x ) { *x = 3 } // C
> def setValue( x ): x = 3 # Python
>
>whoops, we cannot modfiy integers in-place, how invonvenient.

Python is not C or C++. You must change your mindset.

>ok, here's a third question, and it builds on the above inquiry
>regarding a lack of an assignment operator. What happens when I want
>to do convert this for loop:
>
> for i,j in dest, src:
> dest[ i ] = src[ j ]
>

>into a fast map() expression:
>
> map( dest.assign_operator, src )

Who says that map() is faster? It certainly is not any more
readable. Why do you want to do such a thing? Premature
optimization is the root of all evil (in programming).

Besides, if you want to copy the sequence why don't you just use
copy.copy()?

>I cannot use filter() to narrow down the list to only the elements
>that I want and then copy it into another list with src.copy().

Sorry, I don't understand what the problem is here:

new_list = filter(my_predicate, my_list)

Why would you want to use copy()? Why do you need an assigment
operator?


Neil

Tim Peters

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to pytho...@python.org
[Interrupting Michael Hudson's fine advice to inject a nit]

[Roey Katz]


> this brings up another concern. Given
> the following definition:
>
> class A:
>
> def __getattr__( self, name ):
> return -1
> def __setattr__( self, name, val ):
> self.__dict__[ name ] = val
>
> I see that self.__dict__ must be a special variable
> in that setting it somehow avoids a recursive call
> to __setattr__()?

[Michael]


> Yup. Look in Objects/classobject.c around about line 580
> if you want the gory details.

While true, it doesn't apply to Roey's example: he's not setting __dict__.
He's binding a key *of* self.__dict__; self.__dict__ itself is merely
referenced. So Roey should really be wondering why the reference to
self.__dict__ isn't invoking __getattr__ (&, of course, that's also due to
special-case __dict__ magic, but in __getattr__'s implementation).

I don't mean to be overly picky; it's just that the excruciating details are
vital when mucking with __getattr__/__setattr__, and *any* small
misconception about them will eventually bite hard.

> ...


> Bizarrely,
>
> filter(dest.append,src)
>
> is probably more memory efficient (the map form conses up a
> list of return values, but as append always returns None -
> which is false - filter `rejects' every element) - but if
> you write code like this, you deserve to lose.

Yes, pointing him to the most bizarre endcases of Python behavior will
surely aid him in "resetting his brain" <wink>.

Guido gave some excellent semi-exasperated advice (similar in spirit to
parts of Michael's advice that I've snipped) many moons ago, when the whole
newsgroup was temporarily filled with msgs of this character: he invited
people to just *try* writing a Python program without using any __xxx__
hooks. I expect some people were amazed at how much easier their lives got!
If he were to get that exasperated again today, I bet he'd expand his
invitation to include avoiding map, filter, reduce and lambda too.

you're-not-ready-to-use-them-in-python-before-you're-
happy-without-them-ly y'rs - tim


Michael Hudson

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to
"Tim Peters" <tim...@email.msn.com> writes:

> [Interrupting Michael Hudson's fine advice to inject a nit]
>
> [Roey Katz]
> > this brings up another concern. Given
> > the following definition:
> >
> > class A:
> >
> > def __getattr__( self, name ):
> > return -1
> > def __setattr__( self, name, val ):
> > self.__dict__[ name ] = val
> >
> > I see that self.__dict__ must be a special variable
> > in that setting it somehow avoids a recursive call
> > to __setattr__()?
>
> [Michael]
> > Yup. Look in Objects/classobject.c around about line 580
> > if you want the gory details.
>
> While true, it doesn't apply to Roey's example: he's not setting __dict__.
> He's binding a key *of* self.__dict__; self.__dict__ itself is merely
> referenced. So Roey should really be wondering why the reference to
> self.__dict__ isn't invoking __getattr__ (&, of course, that's also due to
> special-case __dict__ magic, but in __getattr__'s implementation).

Actually I noticed this; line 580 is in instance_getattr1.

> I don't mean to be overly picky; it's just that the excruciating details are
> vital when mucking with __getattr__/__setattr__, and *any* small
> misconception about them will eventually bite hard.

Oh yes, that much is true.

[schnipp]

> Yes, pointing him to the most bizarre endcases of Python behavior will
> surely aid him in "resetting his brain" <wink>.

Sorry. I get carried away in situations like that. As you might well
know, if you remember where the bytecodehacks started...



> Guido gave some excellent semi-exasperated advice (similar in spirit to
> parts of Michael's advice that I've snipped) many moons ago, when the whole
> newsgroup was temporarily filled with msgs of this character: he invited
> people to just *try* writing a Python program without using any __xxx__
> hooks. I expect some people were amazed at how much easier their lives got!
> If he were to get that exasperated again today, I bet he'd expand his
> invitation to include avoiding map, filter, reduce and lambda too.

I'd expect so to; most of the Python code that I ever had trouble
understanding used map & co extensively. Rewriting it to use Python
loops definitely helps.

> you're-not-ready-to-use-them-in-python-before-you're-
> happy-without-them-ly y'rs - tim

What follows is pure opinionated speculation (or drivel, if you like).

Python makes it soooo easy to write readable code that I think it's
harder than in many languages to spot good practise. In C++ or Lisp or
Haskell or many other languages, if your logic's getting confused it's
generally obvoius (becuase the code has become nauseatingly hard to
read). Python is more subtle.

Things I find that almost uniformly improve code readability and
reliability include:

writing short functions
using Python loops
avoiding lambdas
never *ever* using "import *"
using classes where I might use a fake closure
remebering that I'm programming Python, and that using an idiom from
another programming language is *not* necessarily a good idea

I'm gradually forming the opinion that writing *really* good code in
Python is no easier than in any other language, it's just that writing
merely very good code is much easier.

thanks-for-listening-ly y'rs
Michael


Aahz Maruch

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to
In article <000001bf651d$f05ac240$132d153f@tim>,

Tim Peters <tim...@email.msn.com> wrote:
>
>Guido gave some excellent semi-exasperated advice (similar in spirit to
>parts of Michael's advice that I've snipped) many moons ago, when the whole
>newsgroup was temporarily filled with msgs of this character: he invited
>people to just *try* writing a Python program without using any __xxx__
>hooks. I expect some people were amazed at how much easier their lives got!
>If he were to get that exasperated again today, I bet he'd expand his
>invitation to include avoiding map, filter, reduce and lambda too.

I assume that Guido's advice specifically excluded __init__; otherwise,
it makes no sense to me.
--
--- Aahz (@netcom.com)

Androgynous poly kinky vanilla queer het <*> http://www.rahul.net/aahz/
Hugs and backrubs -- I break Rule 6

Have a *HAPPY* day!!!!!!!!!!

Aahz Maruch

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to
In article <m31z79w...@atrus.jesus.cam.ac.uk>,

Michael Hudson <mw...@cam.ac.uk> wrote:
>
>I'm gradually forming the opinion that writing *really* good code in
>Python is no easier than in any other language, it's just that writing
>merely very good code is much easier.

Bingo. And writing clean, efficient code gets changed from extremely
difficult to simply "difficult".

Tim Peters

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to pytho...@python.org
> ... he invited people to just *try* writing a Python program
> without using any __xxx__ hooks. ...

[Aahz]


> I assume that Guido's advice specifically excluded __init__;
> otherwise, it makes no sense to me.

No, he didn't specifically exclude it -- I suppose he figured he was talking
to grownups <wink>.

__init__-isn't-really-"a-hook"-ly y'rs - tim


Skip Montanaro

unread,
Jan 26, 2000, 3:00:00 AM1/26/00
to Scott Johnson

Scott> I've read the tutorial and I don't get lambda.

Scott,

You're probably not alone. ;-)

The result of executing a lambda is nothing more than an unnamed function
object. It has some rather peculiar syntactic limitations that make it
appear very odd to the untrained eye.

You can safely ignore lambda for the time being and just use named
functions. If/when you need it, you'll probably realize it.

(Fred, maybe discussion of lambda doesn't belong in the tutorial...)

Skip Montanaro | http://www.mojam.com/
sk...@mojam.com | http://www.musi-cal.com/
847-971-7098
"Languages that change by catering to the tastes of non-users tend
not to do so well." - Doug Landauer


Scott Johnson

unread,
Jan 27, 2000, 3:00:00 AM1/27/00
to
I've read the tutorial and I don't get lambda.

----------
"Tim Peters" <tim...@email.msn.com> wrote...

> [Interrupting Michael Hudson's fine advice to inject a nit]
>
> [Roey Katz]
> > this brings up another concern. Given
> > the following definition:
> >
> > class A:
> >
> > def __getattr__( self, name ):
> > return -1
> > def __setattr__( self, name, val ):
> > self.__dict__[ name ] = val
> >
> > I see that self.__dict__ must be a special variable
> > in that setting it somehow avoids a recursive call
> > to __setattr__()?
>
> [Michael]
> > Yup. Look in Objects/classobject.c around about line 580
> > if you want the gory details.
>
> While true, it doesn't apply to Roey's example: he's not setting __dict__.
> He's binding a key *of* self.__dict__; self.__dict__ itself is merely
> referenced. So Roey should really be wondering why the reference to
> self.__dict__ isn't invoking __getattr__ (&, of course, that's also due to
> special-case __dict__ magic, but in __getattr__'s implementation).
>

> I don't mean to be overly picky; it's just that the excruciating details are
> vital when mucking with __getattr__/__setattr__, and *any* small
> misconception about them will eventually bite hard.
>

> > ...
> > Bizarrely,
> >
> > filter(dest.append,src)
> >
> > is probably more memory efficient (the map form conses up a
> > list of return values, but as append always returns None -
> > which is false - filter `rejects' every element) - but if
> > you write code like this, you deserve to lose.
>

> Yes, pointing him to the most bizarre endcases of Python behavior will
> surely aid him in "resetting his brain" <wink>.
>

> Guido gave some excellent semi-exasperated advice (similar in spirit to
> parts of Michael's advice that I've snipped) many moons ago, when the whole

> newsgroup was temporarily filled with msgs of this character: he invited


> people to just *try* writing a Python program without using any __xxx__

> hooks. I expect some people were amazed at how much easier their lives got!
> If he were to get that exasperated again today, I bet he'd expand his
> invitation to include avoiding map, filter, reduce and lambda too.
>

Aahz Maruch

unread,
Jan 27, 2000, 3:00:00 AM1/27/00
to
In article <_nOj4.894$yY6....@news.goodnet.com>,

Scott Johnson <sjoh...@csnet.net> wrote:
>
>I've read the tutorial and I don't get lambda.

So don't use it! I've been programming for more than twenty years, and
I don't get lambda, either. (Not that I've tried very hard, mind you;
functional programming doesn't do much for me.) Even Guido admits that
lambdas may have been a mistake, so I'd strongly suggest that you
concentrate on learning the rest of Python first.

0 new messages