[Tutor] Equivalent of a Subroutine in Python?

D-Man dsh8290@rit.edu
Thu, 1 Feb 2001 17:18:14 -0500


Except for some minor philosophical issues,

subroutine is function is method is procedure is subprogram

Different communities have different names for the same concept.
Functions are what you want here.  The problem you are running into is
Python's scope and namespace rules.

Ex:

>>> def mutate( ) :
...     """ this function will give a new value for s """
...     s = s + "Hello World"
...
>>> s = "Foo "
>>> mutate( )
>>> print s
Foo
>>>

What happened here?  The value didn't change.  There are 2 reasons for
that.  First, the function body has a local namespace.  Those names
don't exist outside of the function.  Assignment, in Python, is
different than in most languages.  In, say, C/C++ assignment will
modify the value of the memory that the variable name refers to (is
bound to).  In Python, assignment is simply a rebinding.  Everything
in Python is a reference.  If a name doesn't yet exist, the
"assignment" will create the name, *in the local namespace*.  Ok,
knowing this, I'll try my above example again.

>>> def mutate( ) :
...     global s
...     s = s + "Hello World"
...
>>> s = "Foo "
>>> mutate( )
>>> print s
Foo Hello World
>>>


This is closer to what you are looking for, I think.  The 'global'
keyword notifies the interpreter that you want to use a variable from
outside the local namespace.  This isn't necessary for reading a
variable, but to assign to it (rebind it) it is necessary.  Without
the global statement, I would have created a new binding in the
function's local namespace, and the effects would not be visible
outside of the function.


There is another issue to consider when trying to modify variables.
Some variables are immutable, while other are mutable.  Immutable
variables can't have their /value/ changed, but can still be rebound
to a new object (value).  Strings, integers, and tuples are some of
the immutable types in python.  Lists and classes are mutable.  An
example:

>>> def mutate( s ) :
...     s = s + "Hello World"
...
>>> a_string = "Foo "
>>> mutate( a_string )
>>> print a_string
Foo
>>>

The argument 's' was rebound /inside/ the function to point to a new
string whose value was "Foo Hello World".  The a_string variable is
still bound to the original string whose value is still "Foo".

Now I'll try with a list, since lists are mutable.

>>> def mutate( l ) :
...     """ try mutating a list """
...     l = l + [ 3 , 4 , 5 ]
...
>>> a_list = [ 1 , 2 ]
>>> mutate( a_list )
>>> print a_list
[1, 2]
>>>

The problem here is the namespace the new list is bound in.  The
operator "+" on a list doesn't modify the list, but instead returns a
new list that is the concatenation of the operands.

>>> def mutate( l ) :
...     l += [ 3 , 4 , 5 ]
...
>>> a_list = [ 1 , 2 ]
>>> mutate( a_list )
>>> print a_list
[1, 2, 3, 4, 5]
>>>

Version 2.0 of the interpreter added augmented assignment.  For
immutable objects, the value isn't changed and the new object is bound
to the left hand side.  (It is just a shorthand notation)  For mutable
objects it will modify the object, /and/ return a refernce to the
object.  The return is necessary otherwise your identifier won't refer
to any objects anymore.

In older versions as well as newer versions of the interpreter, the
following will also work:

>>> def mutate( l ) :
...     l.extend( [ 3 , 4 , 5 ] )
...
>>> a_list = [ 1 , 2 ]
>>> mutate( a_list )
>>> print a_list
[1, 2, 3, 4, 5]
>>>


What kind of background are you coming from?  If I remember correctly,
gosub is from BASIC (but I haven't done any BASIC programming).

If you can provide some examples of what you are trying to do (the
python code you have that isn't working right) we can help you to see
how python's semantics are working and how to modify it to give you
the semantics you want.


You can start out using stand-alone functions, but I much prefer using
classes for (most) of my work.  (there are situations where a
stand-alone function is a better choice though)  Simply put, a class
is a set of data and a set of functions that operate on that data.
You can create multiple instances of a class and each will have its
own set of that data.

HTH,
-D


On Wed, Jan 31, 2001 at 05:12:29PM -0500, Seelinger, Bruce wrote:
| Hello,
| 
| Another question from someone totally new to Python. Is there an equivalent
| in Python to a sub-routine, (e.g. gosub and return).  I want to create a
| modular program with sub-routines to perform distinct tasks wihin the
| program for organizational and debugging purposes, etc.  Is the only (or
| best) way to do this is with modules?  A function works but the values
| obtained within the function do not appear to be valid outside of that
| function.  I guess I am looking for the best approach to create the
| subroutines for execution from the main flow of the program.
| 
| Thanks for any assistance!
| 
| Regards,
| 
| Bruce Seelinger