So, the title doesn't make a lot of sense, but what I have going on is:
I have a PYT containing several tools.
I've added a class variable to one of the tools that calls a function to create a dictionary.
class Toolbox:
def __init__(self):
self.label = ""
self.alias = ""
self.tools = [tool1, tool2]
class tool1:
def createDict():
retDict = {}
return retDict
retDict = createDict()
def __init__(self):
self.label = ""
self.description = ""
def getParameterInfo(self):
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
pass
return
def postExecute(self, parameters):
return
The issue that I'm having is that the function (Lines 7-9) to create that class variable (Line 10) is called when I initialize the toolbox, not when I initialize that particular tool. This is making opening the toolbox take longer than it should, particularly given that I might want to use the other several tools and don't care about that dictionary getting created.
How can I make it so the function doesn't get called until I open that tool? I'm cool with waiting however long I need to; I just don't want to wait until I need to.
I'd be cool with like, adding it as a derived parameter in getParameterInfo(), but there isn't an option in Parameter data types to just use a python dictionary.
Any ideas? Thanks!
Solved! Go to Solution.
Okay, I figured out two solutions here.
Solution 1 (unpreferred): Create a parameter and load the dictionary into it as a string (not preferred). This is kind of clunky and you end up having to import json for it to work. Also, this is a specific solution for a specific datatype, so not great.
class Toolbox:
def __init__(self):
self.label = ""
self.alias = ""
self.tools = [tool1, tool2]
class tool1:
def createDict():
retDict = {}
return retDict
def __init__(self):
self.label = ""
self.description = ""
def getParameterInfo(self):
param0 = arcpy.Parameter(displayName="Dictionary",
name="retDict",
datatype="GPString",
parameterType="Required",
# multivalue= True,
direction="Input")
param0.value = str(tool1.createDict()).replace("'",'"')
params = [param0]
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
import json
retDict = loads(parameters[0].value)
return
def postExecute(self, parameters):
return
Solution 2 (preferred): Create a class variable, but just don't run it until you initialize the tool. That is, populate it in getParameterInfo().
This seems a lot cleaner -- no changing between data types, no extra modules, etc.
class Toolbox:
def __init__(self):
self.label = ""
self.alias = ""
self.tools = [tool1, tool2]
class tool1:
def createDict():
retDict = {}
return retDict
# I set the variable to initialize empty.
# This is in part so I don't forget that it's there.
retDict = {}
def __init__(self):
self.label = ""
self.description = ""
def getParameterInfo(self):
param0 = ...
# I used setattr() because doing self.retDict
# didn't take the change.
setattr(tool1, "retDict", tool1.createDict())
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
pass
return
def postExecute(self, parameters):
return
Hopefully this helps someone down the line.
Okay, I figured out two solutions here.
Solution 1 (unpreferred): Create a parameter and load the dictionary into it as a string (not preferred). This is kind of clunky and you end up having to import json for it to work. Also, this is a specific solution for a specific datatype, so not great.
class Toolbox:
def __init__(self):
self.label = ""
self.alias = ""
self.tools = [tool1, tool2]
class tool1:
def createDict():
retDict = {}
return retDict
def __init__(self):
self.label = ""
self.description = ""
def getParameterInfo(self):
param0 = arcpy.Parameter(displayName="Dictionary",
name="retDict",
datatype="GPString",
parameterType="Required",
# multivalue= True,
direction="Input")
param0.value = str(tool1.createDict()).replace("'",'"')
params = [param0]
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
import json
retDict = loads(parameters[0].value)
return
def postExecute(self, parameters):
return
Solution 2 (preferred): Create a class variable, but just don't run it until you initialize the tool. That is, populate it in getParameterInfo().
This seems a lot cleaner -- no changing between data types, no extra modules, etc.
class Toolbox:
def __init__(self):
self.label = ""
self.alias = ""
self.tools = [tool1, tool2]
class tool1:
def createDict():
retDict = {}
return retDict
# I set the variable to initialize empty.
# This is in part so I don't forget that it's there.
retDict = {}
def __init__(self):
self.label = ""
self.description = ""
def getParameterInfo(self):
param0 = ...
# I used setattr() because doing self.retDict
# didn't take the change.
setattr(tool1, "retDict", tool1.createDict())
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
pass
return
def postExecute(self, parameters):
return
Hopefully this helps someone down the line.