[GIS] Using Custom Functions in Python Toolbox

arcgis-10.1arcpypython-toolbox

I am trying to put together a python toolbox (Arc 10.1) and would like to use a defined function in my code. The function is:

'sys' is imported at the top of the file    
def listdirs(folder):
        return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]

It's a handy little bit of code I picked up on stackexchange that returns a list of folders in a given path.

I can't seem to figure out how to integrate it into the toolbox, everywhere I put it seems to disagree with the toolbox. Initially I had it in the def execute(self,parameters,messages) block. That didn't work, so I moved it outside of that and into the class level. I also tried putting it outside of the class.

The toolbox compiles without any errors (Using the 'Check Syntax' tool in the context menu in ArcCatalog) but when I run it my script fails the first time the function is called. No specific error is thrown, but my script exits through the except statement and doesn't finish the try block

Should I put it into an external file and then import that like I do arcpy,sys,traceback etc? Does anyone know if there are certain restrictions to using custom functions inside of a python toolbox and if so, what they are?


It seems that the real issue was that I was including sys and not os like I should have been. Rookie mistake. Anyhow, the script seems to be running nicely now, python toolboxes are great and are making my life much simpler.

Regarding the crux of my original question for any folks curious in the future – it doesn't seem to matter where you define a custom function in the python toolbox. As long as it has the classes that ArcGIS needs to know what to do with it anything else is ephemera.

Best Answer

import arcpy
import sys
import os

class Tool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "My Tool"
        self.description = ""
        self.canRunInBackground = False

    def listdirs(self, folder):
        return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]

...

Then, call it anywhere in the the tool (for example, in the execute method):

self.listdirs(r"C:\MyFolder")
Related Question