Returning Python Types from Custom Commands

 
 
 

When setting up your return values from a custom command authored in Python, you need to be aware that you cannot pass native Python dictionaries and Python custom classes as-is:

Using Python Dictionaries as Return Values

The Python native dictionary type does not conform to any of the possible data types that Softimage allows as return values from custom commands. As a workaround, you can use an ActiveX scripting dictionary as demonstrated in the following code snippet from a self-installing custom command:

#---------
def testdictionary_Execute(  ):
	import win32com.client
	oDict = win32com.client.Dispatch( "Scripting.Dictionary" )

	oDict[ 'key1' ] = 123
	oDict[ 'key2' ] = 45
	oDict[ 'key3' ] = 6789
	
	return oDict
#---------

Using Custom Python Classes as Return Values

A Python custom command can return a Python object whose functions and attributes are available as methods and properties to VBScript and JScript. Follow these steps:

  1. Set the following attributes of the Python class to define which methods and attributes are exposed.
    • _public_methods_ – List of public functions
    • _public_attrs_ – List of public attributes (both read-only and read-write)
    • _readonly_attrs_ – List of read-only attributes
  2. Wrap the instance of the class being returned using the win32com.server.util.wrap( ) function.

    The custom command creates the object and returns it.

The following self-installing plug-in returns a Python object that is usable from VBScript and JScript.

 # This class will be exported to VBScript and JScript
class TestPython:
    # Declare list of exported functions
    _public_methods_ = ['GetAnswer']
    # Declare list of exported attributes
    _public_attrs_ = ['exclamation', 'answer']
    # Declare list of exported read-only attributes
    _readonly_attrs_ = ['answer']

    # Class init:
    def __init__(self):
    # Initialize exported attributes
	       self.exclamation = 1
	       self.answer = 42
		      # Perfectly valid to have other non exported attributes
    # Exported function
    def GetAnswer(self, question):
	       return "The answer to " + str(question) + " is " + str(self.answer) + "!"*self.exclamation
	       # Perfectly valid to have other non exported functions
		
true = 1

# Traditional Plugin installation
def XSILoadPlugin( in_reg ):
    in_reg.Author = "Command Wizard User"
    in_reg.Name = "TestPython Plug-in"
    in_reg.Major = 1
    in_reg.Minor = 0
    in_reg.RegisterCommand( "TestPython","TestPython" )
    return true

def TestPython_Init( io_Context ):
    oCmd = io_Context.Source
    oCmd.ReturnValue = true
    return true

def TestPython_Execute(  ):
    oClass = TestPython()
    import win32com.server
    # Class MUST be wrapped before being returned
    return win32com.server.util.wrap(oClass)

The following VBScript uses the Python object.

set a = TestPython()
'INFO : TestPython_Execute called
LogMessage a.GetAnswer("life, the universe, everything")
'INFO : The answer to life, the universe, everything is 42!
a.exclamation = 10
LogMessage a.GetAnswer("life, the universe, everything")
'INFO : The answer to life, the universe, everything is 42!!!!!!!!!!

You can choose whether to create a new object each time (as shown in the example), or to share a single instance of the object. The single instance of the object is stored as a global variable in the plug-in and all scripts can share the data.

For more information, see these Python sources:

Creative Commons License Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License