Where to create the function that can be called from several tools?

1680
8
Jump to solution
08-15-2013 05:48 AM
ionarawilson1
Occasional Contributor III
I created a python toolbox with a bunch of tools. I have to create a list and a dictionary (very long) for almost all the tools - The list and dictionary have the same elements for all the tools that will use them. I  was thinking I could create a function to first create this list and dictionary and then call if from the tools that will use them. If this is possible, where in the file, should I create this function? thank you!!!
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
DaveBarrett
Occasional Contributor
Hi,

I have just started experimenting with the python toolbox capability and had similar issues. I found the easiest solution to be a python module at the same level as the .pyt file with the necessary functions in there.

It should be possible to place a function at the very top of the .pyt file outside of the class structure and this should then be available to any of the tools within that file. I haven't tested this fully but I should have a working example in the next couple of days.

eg:

import arcpy  def commonFunction():     print "TRUE"  class Toolbox(object):     def __init__(self):         """Define the toolbox (the name of the toolbox is the name of the         .pyt file)."""         self.label = "Toolbox"         self.alias = ""          # List of tool classes associated with this toolbox         self.tools = [Tool]   class Tool(object):     def __init__(self):         """Define the tool (tool name is the name of the class)."""         self.label = "Tool"         self.description = ""         self.canRunInBackground = False      def getParameterInfo(self):         """Define parameter definitions"""         params = None         return params      def isLicensed(self):         """Set whether tool is licensed to execute."""         return True      def updateParameters(self, parameters):         """Modify the values and properties of parameters before internal         validation is performed.  This method is called whenever a parameter         has been changed."""         return      def updateMessages(self, parameters):         """Modify the messages created by internal validation for each tool         parameter.  This method is called after internal validation."""         return      def execute(self, parameters, messages):         """The source code of the tool."""         test = commonFunction()         return


For the project I am currently working on we are planning to move all the tools for the toolbox into a package including all useful functions due to the large number of tools making the .pyt very long and difficult to read / edit.

Hope this had some use

Dave

View solution in original post

0 Kudos
8 Replies
T__WayneWhitley
Frequent Contributor
Interesting topic - I'll be brief, as there are a number of ways to set this up.

When you're calling python 'tools', you're really calling the underlying associated py files.  You have 'site packages' stored on your system as arcpy was installed in an specifically made ArcGIS install directory.  You can create your own too -- I think there's webhelp that may go into this, Toolshare I think ESRI was calling it.

As a quick example, let's say you want to 'see' the current system directories recognized by python-
You can do a simple command line execution of 'import sys', then 'sys.path', which returns pathnames where python seeks function files you may have built.

...an oversimplification is that I saved a print command in a test py file, then saved it to one of the default directories (I chose C:\Python26\ArcGIS.....blah blah...  Say I named the file theFile.py.

Then from IDLE, I called the file via import theFile.py ---- it simply executes the print command.

You can build from there.


Enjoy,
Wayne
0 Kudos
ionarawilson1
Occasional Contributor III
Thank you Wayne, but I wanted is to create a function in the python toolbox file (.pyt), not call a file to do that. Is that possible?
0 Kudos
T__WayneWhitley
Frequent Contributor
Ah, sorry, still not 100% sure what you mean? 

Do you mean call a function from within the same script?....call another script tool or script within the same toolbox structure?  I think the latter is what you mean and I'm beginning to understand where you're going (I think).  PYT is relatively new and there are new ways to 'form' the call to other parts of the toolbox, I think.  My experience with this is limited to say the least - but I'm interested, so I'll be watching this thread for more informed answers.

Thanks,
Wayne

EDIT:
....very interesting, maybe the following will provide some kind of assistance to you:

Toolbox to Python Toolbox Wrapper
http://www.arcgis.com/home/item.html?id=83585412edd04ae48bdffea3e1f7b2e7
0 Kudos
ionarawilson1
Occasional Contributor III
Thank you Wayne. I actually used that script to create my toolbox. Because I have to create the same list in many tools inside the toolbox, I need to create a function that creates this list somewhere and then call the function to create the list in each tool
0 Kudos
DaveBarrett
Occasional Contributor
Hi,

I have just started experimenting with the python toolbox capability and had similar issues. I found the easiest solution to be a python module at the same level as the .pyt file with the necessary functions in there.

It should be possible to place a function at the very top of the .pyt file outside of the class structure and this should then be available to any of the tools within that file. I haven't tested this fully but I should have a working example in the next couple of days.

eg:

import arcpy  def commonFunction():     print "TRUE"  class Toolbox(object):     def __init__(self):         """Define the toolbox (the name of the toolbox is the name of the         .pyt file)."""         self.label = "Toolbox"         self.alias = ""          # List of tool classes associated with this toolbox         self.tools = [Tool]   class Tool(object):     def __init__(self):         """Define the tool (tool name is the name of the class)."""         self.label = "Tool"         self.description = ""         self.canRunInBackground = False      def getParameterInfo(self):         """Define parameter definitions"""         params = None         return params      def isLicensed(self):         """Set whether tool is licensed to execute."""         return True      def updateParameters(self, parameters):         """Modify the values and properties of parameters before internal         validation is performed.  This method is called whenever a parameter         has been changed."""         return      def updateMessages(self, parameters):         """Modify the messages created by internal validation for each tool         parameter.  This method is called after internal validation."""         return      def execute(self, parameters, messages):         """The source code of the tool."""         test = commonFunction()         return


For the project I am currently working on we are planning to move all the tools for the toolbox into a package including all useful functions due to the large number of tools making the .pyt very long and difficult to read / edit.

Hope this had some use

Dave
0 Kudos
RhettZufelt
MVP Frequent Contributor
Ionara,

have you heard of python pickle?

This will let you save the dictionary to a file, then extract that dictionary back out when needed so you don't need to regenerate all the time.

I think a function/module, though called from another script would still need to regenereate the dict.  Not sure I completely understand what you are after, but I think pickle is what you want.

http://wiki.python.org/moin/UsingPickle

R_
0 Kudos
ModyBuchbinder
Esri Regular Contributor
If I understand you correctly what you need is a class with functions in it.
Check C:\Program Files (x86)\ArcGIS\Desktop10.1\ArcToolbox\Scripts\ConversionUtils.py for a good example.
There are many other scripts in the same directory that uses this util function (for example BatchProject.py).

Have Fun
Mody
0 Kudos
ionarawilson1
Occasional Contributor III
Thank you Dave, Rhett and Mody. I think all of your answers are correct and very helpful. Rhett, I will  use pickle in the future, it will be very helpful. For now, I tested Dave's idea and it worked so I will go with his answer since I prefer not to rely on an external file (but it will definitely need pickle for another procedure in this project so thanks for that!) and he was the first one to post. Mody thank you for pointing that. I need to learn more about creating classes but it looks like it would work also! Thank you again guys!
0 Kudos