[GIS] Organizing files for large Python script tool

arcpypython-script-tool

I am writing a lengthy ArcPy tool and am working with multiple python scripts, simply for organization's sake. Everything runs well when I run it from the command line, but now that I am starting to think about converting it to a script tool, I am getting a headache.

My previous structure:

  • parameters.py : lists all globals (parameters, functions, variables)

  • a_functions.py, b_functions.py, etc. : lists functions for use in main code, imports parameters with *

  • maincode.py : calls functions from *_functions.py, imports parameters with *

The structure is quite neat, and although it may not be ideal from a file structure standpoint, it works well enough (chime in if I am doing something horribly wrong).

Now that I need to load a file into the script tool that defines the parameters, I can't simply move all the parameters to the main code file, as I need to import them as globals to the other files, and importing with * will also import all the globals local to maincode.py.

I could just move everything into one file, but all the organization would be lost and it would be a big mess.

Does anyone have any suggestions who has built a lengthy arcpy tool with multiple files before?

Best Answer

Use a package structure. __init__.py can hold your package scope variables. The package modules can access those variables easily, calling scripts can set them if they need to and everything is all nicely wrapped up in a single directory.

e.g.

#  |  mainscript.py
#  \--somepackage
#     |  __init__.py
#     |  script1.py
#     |  script2.py

#----------------------------
#mainscript.py
#----------------------------
import somepackage

#set some variables
somepackage.args=['a','b','c']
somepackage.kwargs={'d':1,'e':2,'f':3}

#Call some functions
somepackage.script1.main()
somepackage.script2.main()

#----------------------------
#somepackage.__init__.py
#----------------------------
__all__=['script1','script2']
import script1,script2

#Some defaults
args=[]
kwargs={}
somevar=1
anothervar=2

#----------------------------
#somepackage.script1.py
#----------------------------
import somepackage
def main():
    print somepackage.args
    print somepackage.somevar

#----------------------------
#somepackage.script2.py
#----------------------------
import somepackage
def main():
    print somepackage.kwargs
    print somepackage.anothervar
Related Question