Softimage SDK Programmer's Guide > Script Development > Python Scripting >

# 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

- Using Custom Python Classes as Return Values

## 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:

- http://docs.activestate.com/activepython/2.5/full_toc.html – Contains information about COM-wrapping custom Python classes and how to expose its methods and properties to COM using the policy attributes

- http://oreilly.com/catalog/pythonwin32/chapter/ch12.html – This is a sample chapter (Implementing COM Objects in Python) from Python Programming on Win32 that also explains working with COM. However, you can skip the CLSID/ProgID information because custom commands already return a fully created object.