[Tutor] Passing objects [return statements and OUTPUT parameters]

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Thu Jul 8 20:14:52 CEST 2004



On Thu, 8 Jul 2004, Alan Gauld wrote:

> > >>> def foo(shape):
> > shape = SWFShape()
> > return shape
> > >>> r = ""
> > >>> foo(r)
> > <ming.SWFShape instance at 0x00B9CB20>
> > >>> r
> > ''
> > >>>
> >
> > I am somewhat mystified by the above behaviour. A class instance is
> > instantiated, but r remains a string.
>
> Of course. You create the shape inside the function,
> after the function finishes the shape is lost. If you want to keep
> it you need to assign the function return value to a variable:
>
> >>> r = foo(r)
> >>> r
> <ming.SWFShape instance at 0x00B9CB20>


Hi Alex,


There's some confusion here; I think that you may be thinking of "OUTPUT"
parameters, like the ones provided in Fortran or C.


If we want to get back several results from a function, in those other
languages, we'd set aside a few parameters that aren't used for input, but
rather, for storing the results of some process.


For example, let's say we were writing a 'divmod()' function in C that
provides both the quotient and remainder of some division:

/*** C code ***/
#include <stdio.h>

void divmod(int m, int n, int *q, int *r) {
    *q = m / n;
    *r = m % n;
}

int main() {
    int x, y;
    int q, r;
    printf("Enter two integers, each on a separate line:\n");
    scanf("%d %d", &x, &y);
    divmod(x, y, &q, &r);
    printf("The quotient and remainder is: %d, %d", q, r);
    return 0;
}
/******/

In this C code, 'q' and 'r' are used as OUTPUT variables, just to store
the results of 'divmod()'.  We'd say that we're using 'divmod' for its
side-effect of modifying the last two parameters.  Fortran supports a
similar effect.



But Python programs typically do not use OUTPUT-style parameters,
primarily because it's easy to return multiple values with a 'return'
statement:

### Python code ###
def divmod(m, n):
    """Given integers m, n, returns the quotient and remainder of dividing
    m by n as a 2-tuple."""
    q = m / n
    r = m % n
    return (q, r)

def main():
    print "Input two integers, each on a separate line:"
    x = input()
    y = input()
    q, r = divmod(x, y)
    print "The quotient and remainder is: %d, %d" % (q, r)
######


The advantage of avoiding OUTPUT parameters is that we are not necessarily
constrained to set aside variables just for doing things.



If we were minimalistic, we could even reduce the program above to:

###
def divmod(m, n):
    """Given integers m, n, returns the quotient and remainder of dividing
    m by n as a 2-tuple."""
    return (m/n, m%n)

def main():
    print "Input two integers, each on a separate line:"
    print "The quotient and remainder is: %d, %d" % divmod(input(),
                                                           input())
###

And here we don't even do any assignments.  This might be a little
extreme, though.  *grin*




Going back to your original function:

###
def foo(shape):
    shape = SWFShape()
    return shape
r = ""
foo(r)
###

the bug here is a misunderstanding of how 'return' works --- the code is
trying to treat 'shape' as an OUTPUT parameter, but that's not how
'return' is intended to be used.

Try:

###
def foo():
    shape = SWFShape()
    return shape

r = foo()
###


or even:


###
def foo():
    return SWFShape()

r = foo()
###


Hope this helps!



More information about the Tutor mailing list