How to return a simple variable from a function (still newbie) ?

Carsten Haese carsten at uniqsys.com
Thu Dec 28 14:58:00 EST 2006


On Thu, 2006-12-28 at 19:49 +0100, Stef Mientki wrote:
> [...]
> When I replace the assignment to "filter_prev", by a loop,
> the function works as expected.
> <Python>
>    #filter_prev = Extended [ len(Signal_IN) : ]
>    for i in range( len(filter_prev )):
>      filter_prev[i] = Extended [ len(Signal_IN) + i ]
> </Python>

Let's examine the fundamental difference between the statements

filter_prev = Extended [ len(Signal_IN) : ] and

filter_prev[i] = Extended [ len(Signal_IN) + i ] .

The first statement is an assignment to the local name filter_prev.
Prior to that assignment, filter_prev was a reference to whatever object
was passed into your function in the fourth argument slot. The
assignment makes filter_prev become a reference to the list slice
Extended[len(Signal_IN):]. In no way does this affect the object that
filter_prev referred to previously.

The second statement looks a lot like an assignment, but it is not an
assignment. It is a method call. It is equivalent to the method call
filter_prev.__setitem__(i, Extended[len(Signal_IN)+i]), which is asking
the object that filter_prev refers to to change its i-th item. This does
affect the object that filter_prev refers to, which is of course the
same object that, in the global namespace, is known as BP_filter_prev.

The second approach has the desired side-effect of modifying the list
that was passed into the function. The first approach is unable to have
such an effect because assignments modify namespaces, not objects.
You're modifying the local namespace of the chunk_Filter function, and
that change is not made visible to the outside in any way.

If you wish to eliminate the for loop, you can do the following:

filter_prev[:] = Extended[len(Signal_IN):]

This, again, is not an assignment, even though it looks a lot like one.
It is equivalent to a __setslice__ method call, which modifies the
object that filter_prev refers to by making it replace its entire
contents with the contents of the list slice on the right hand side.

If you want to write functions with side-effects, you need to understand
the difference between

somename = someobject

on the one hand and

somename[something] = someobject or somename.something = someobject.

The first is an assignment. It means "make the name somename refer to
the object currently known as someobject". It does not matter if
somename currently refers to an object, and if it does refer to an
object, that object is not modified or even consulted in any way.

The second kind looks superficially like assignments, but they are in
fact __setitem__/__setslice__/__setattr__ method calls in disguise. For
them to succeed, somename must refer to an object that implements the
corresponding method, and those methods will cause the object known as
somename to modify itself.

After all that, you should now be sufficiently discouraged from
attempting to write functions with side effects. :) You can achieve the
same result without side-effects by returning more than one return value
from your function.

Hope this helps,

Carsten.





More information about the Python-list mailing list