The Python assembly is used to execute functions in the Python language, to get results of their work, and to further work with the obtained data. Depending on where modules are located and how Python functions are implemented, the following methods can be used:
The Python.Invoke static method is used if Python modules are located:
In the Python installation folder next to the python3*.dll file or in the nested Scripts folder.
At the specified path which is set using the PythonPath string parameter in the registry key HKEY_CURRENT_USER\SOFTWARE\Foresight\Foresight Analytics Platform\10.0\DevEnv\Python. For details see the Connecting External Modules to Foresight Analytics Platform section.
In the folder with installed Foresight Analytics Platform.
In the folder specified using the IPythonUtils.AddFolderToPythonPath method.
The Python.InvokeModule static method is used if Python modules are added to repository as the Python Module objects. It is necessary to create any additional objects to execute Python functions.
A Python function:
def summXY(x, y):
return x + y
For example, the Fore code implemented using Python.Invoke:
Var
Result: Variant;
Begin
Result := Python.Invoke("sample", "summXY", 100, 500);
If Python modules are located in any different folder, execute the following actions to use Python functions in code:
Create an instance of the PythonUtils class, cast the obtained object to the IPythonUtils type.
Use the IPythonUtils.AddFolderToPythonPath method to create a list of folders, in which Python modules and functions are searched.
Execute the Python function using the IPythonUtils.Invoke method and get result.
Suppose that the summXY function specified above is implemented in the sample.py module, the module is located in the D:\Work\Python\ folder. The following code will execute the summXY function with the specified parameters values:
Var
pUtils: IPythonUtils;
Result: Variant;
Begin
pUtils := New PythonUtils.Create;
pUtils.AddFolderToPythonPath("d:\Work\Python\");
Result := pUtils.Invoke("sample", "summXY", 100, 500);
To execute Python functions implemented in class, execute the following actions in the code:
Create an instance of the PythonClassObject class, cast the obtained object to the IPythonClassObject type.
Use the IPythonClassObject.GetAttr or IPythonClassObject.SetAttr method to get or change class attribute values if function execution result will depend on them.
Execute function of the Python class using the IPythonClassObject.Invoke method and get result.
A Python code:
class Door:
def __init__(self, color, height, width):
self.color = color
self.height = height
self.width = width
def getDoorDescription(self, comment):
return comment + ". Color: " + self.color + " Size: " + str(self.height) + "X" + str(self.width) + " mm"
A Fore code:
Var
pUtils: IPythonUtils;
pObj: IPythonClassObject;
Result: Variant;
Begin
pUtils := New PythonUtils.Create;
pUtils.AddFolderToPythonPath("d:\Work\Python\");
//Create an object of the Door class
pObj := New PythonClassObject.Create("sample", "Door", "Red", 2000, 800);
//Get value of the color attribute
Result := pObj.GetAttr("color");
Debug.WriteLine(Result);
//Change value of the color attribute
pObj.SetAttr("color", "White");
//Execute function of the class instance
Result := pObj.Invoke("getDoorDescription", "Connecting door");
After executing the example, an instance of the Python class with the specified attribute values will be created. Next, the color attribute will be obtained and modified. The getDoorDescription function that returns the string result will be executed.
If default values are determined for parameters of Python function, and the function must be executed by setting only specific parameter values, named parameters can be used. To create a named parameter, use the PythonParameter class. Create parameters with required names and values, send them to the Invoke method.
A Python function:
def getMathOperationWithOperands(a = 0, b = 0, c = 0):
if (a != 0) and (b != 0) and (c != 0):
return ((a + b) * c)
elif (a != 0) and (b != 0):
return a+b
elif (a != 0) and (c != 0):
return a-c
elif (b != 0) and (c != 0):
return b*c
else:
return -1
A Fore code:
Var
pUtils: IPythonUtils;
pObj1, pObj2: IPythonValueObject;
pParam1, pParam2: IPythonParameter;
Result: Variant;
Begin
pUtils := New PythonUtils.Create;
pUtils.AddFolderToPythonPath("d:\Work\Python\");
//Create objects with values
pObj1 := New PythonValueObject.Create(100);
pObj2 := New PythonValueObject.Create(200);
//Create named parameters
pParam1 := New PythonParameter.Create("a", pObj1);
pParam2 := New PythonParameter.Create("c", pObj2);
//Execute function
Result := pUtils.Invoke("sample", "getMathOperationWithOperands", pParam1, pParam2);
After executing the example two named parameters with values are created. The getMathOperationWithOperands Python function will be executed with those parameters.
Simple data types in the Fore language, such as, String, Char, Integer, Double, Decimal, Currency, Boolean, are compatible with data types in the Python language, that, is, str, int, float, bool. Values of these types can be sent to Python functions or obtained after executing Python functions without any additional transformations. It is also possible to work with such Python data types as list and tuple. To work with a list, use the IPythonList interface, to work with a tuple, use the IPythonTuple interface. If the function returns list or tuple, cast result of the Invoke method work to the appropriate interface. To create a new list, use the PythonList class, to create a new tuple, use the PythonTuple class.
A Python function:
def getSizeOfList(l):
return l.__sizeof__()
A Fore code:
Var
pUtils: IPythonUtils;
pList: IPythonList;
pTuple: IPythonTuple;
Result: Variant;
Begin
pUtils := New PythonUtils.Create;
pUtils.AddFolderToPythonPath("d:\Work\Python\");
//Create list and tuple
pList := New PythonList.Create(0, "A", Char.Chr(169));
pTuple := New PythonTuple.Create(0, "A", Char.Chr(169));
//Get information about list
Result := pUtils.Invoke("sample", "getSizeOfList", pList);
Debug.WriteLine("Number of elements in the list: " + pList.Length.ToString);
Debug.WriteLine("Size of memory used (bites): " + Result);
//Get information about tuple
Result := pUtils.Invoke("sample", "getSizeOfList", pTuple);
Debug.WriteLine("Number of elements in the list: " + pTuple.Length.ToString);
Debug.WriteLine("Size of memory used (bites): " + Result);
On executing the example the objects that contain a Python list and tuple are created. Each object will be sent to the getSizeOfList function to get size of the memory it occupies. The number of list and tuple elements, and size of occupied memory are displayed in the development environment console.
All exceptions are handled using the Try…Except…Finally…End Try statement. To handle the errors that may occur on executing a Python function, use the PythonException class.
Var
pUtils: IPythonUtils;
Result: Variant;
Begin
pUtils := New PythonUtils.Create;
pUtils.AddFolderToPythonPath("d:\Work\Python\");
Try
Result := pUtils.Invoke("sample", "summXY", "a", 100);
Debug.WriteLine(Result);
Except On e: PythonException Do
Debug.WriteLine(e.Message);
End Try;
This code executes the summXY function, specified above, with various types parameters. On executing the code, possible exceptional situations are processed using the Try…Except…Finally…End Try operator. If error occurs while execution, text of error will be displayed in the development environment console.
See also: