[Tutor] Accessing variables in main from functions in a module

Alan Gauld alan.gauld at btinternet.com
Sat Oct 31 00:55:09 CET 2009

"Robert Lummis" <robert.lummis at gmail.com> wrote

>I want to move some functions from my "main" program file to a module
> file because the main file is getting too big for convenience.

Good idea!

> functions access arrays (lists of lists) that are defined and
> initialised in the main file. How do I reference the main file arrays
> from statements within the module file?

In  general you don't. You pass the data into the function.
Thats the only (sane) way to make the functions reusable,
by passing in all the data they need to do their job. Its also
the only sane way to avoid the debugging nightmare of
global variables changing under your feet due to hidden
function side effects.

So when you move the functions, rewrite them from

def f(...)
    # stuff

def f(...grid)
    return grid

And when you call them do

grid = mymod.f(...,grid)

That keeps the functions independant and avoids any
mysteries about where your main function variables are
getting changed.

> The overall program solves a game by a recursive method.

In that case even more reason to pass the data in. Recursive
functions opertating on global variables are one of the hardest
things to debug in the programming universe, only beaten by
multiple threads modifying unsynchronised global variables!

> and the presence of a bunch of unchanging housekeeping functions in
> the main file makes it cumbersome to read and edit.

Yes thats one reason to move functions out. But an even better
reason is to logically partition the code into whats reusable
and what is specific to the problem. So consider whether its
really the housekeeping that wants moving or the core algorithms...

> def functionA (row, col, x):
>     grid[row][col] = <a value that depends on x and other values in grid>
> where grid[] is initialised outside of any functions (i.e. in the main).
> So how do I write that function when I move it to a module file? I

As above

def functionA (row, col, x, grid):
     grid[row][col] = <a value that depends on x and other values in grid>
     return grid

and call it with

grid = module.function(row,col,x, grid)

> thought I read somewhere that the main routine has the name "__main__"

A module that is being run directly has the name __main__ not a function.

> I understand that it is best to minimize cross-file references but I
> feel it is warranted in this case.

I doubt it.

> Even if you think it isn't good practice I would like to understand how
> to do it (or else why it can't be done).

You can probably do it by inspecting the call stack using the traceback
module or somesuch, but there'sd really no need.

> Is there some other way to keep files from getting too big?

You can use classes. You could have a Grid class with all the functions
that modify the grid as methods. Then you can create grid objects and
operate on them and each will have its own internal grid. You can then
easily move the class into a separate module as required.


Alan Gauld
Author of the Learn to Program web site

More information about the Tutor mailing list