Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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?

Thanks in advance.

-- EDIT --

So, 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.

Thanks as always for the help in debugging this!

share|improve this question
1  
Can you post any error messages you get beyond 'it doesn't work?' –  Jason Scheirer Jan 16 '13 at 1:31
1  
You need to import os for the command you posted. –  Jay Laura Jan 16 '13 at 1:59
    
As I said in the text of the question it does not throw an error - it simply exits and behaves like the script completed normally. I know this because the debugging info I have in the except clause prints and the script does not complete. It simply tells me the line number that the failure occurred on. @JayLaura - I'll check that out 1st thing tomorrow, although I'm pretty sure that it has worked with import sys in place of import os. –  Kevin Jan 16 '13 at 2:30
    
Have you already seen this? How to Debug Python Toolboxes in 3 Easy Steps –  blah238 Jan 16 '13 at 3:24
1  
It does throw an exception otherwise the code wouldn't reach the except clause. The except clause is hiding the actual error so move the code that isn't working out of the try block. –  Luke Jan 16 '13 at 5:14
add comment

2 Answers 2

up vote 2 down vote accepted

Posting as an answer because I can not post code in a comment. Swapping os for sys will likely solve your issue.

In [1]: import sys

In [2]: os.listdir('/')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/Users/jay/<ipython-input-2-f53adbb13cef> in <module>()
----> 1 os.listdir('/')

NameError: name 'os' is not defined

In [3]: import os

In [4]: os.listdir('/')
Out[4]: 
['.dbfseventsd',
 '.DocumentRevisions-V100',
 '.DS_Store',
 '.file',
 '.fseventsd',
 '.Spotlight-V100',
 '.Trashes',
 '.vol',
 'Applications',

...truncated

share|improve this answer
    
Well, that does look convincing... I'll check this out first thing tomorrow when I'm back at my office. Thanks! –  Kevin Jan 16 '13 at 2:59
add comment
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")
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.