Background
In InterSystems IRIS versions >=2021.2 we can use the accompanying irispython binary to directly write python code on top of our IRIS instances. This lets us use python packages, call methods, make SQL queries, and do nearly anything in Objectscript but pythonic.
For example, below I check if a namespace is present:
#!/usr/irissys/bin/irispython
import iris
# call arbitrary class methods
result = iris.cls('%SYS.Namespace').Exists('USER')
if result == 1:
print(f"Namespace USER is present")
But, what if my method in IRIS has special parameters such as
Output
andByRef
parameters?
How can we useOutput
parameters in irispython?
For example, Ens.Director has a lot of Output parameters on it's methods, how can I use these parameters in python?
Ens.Director:GetProductionStatus
// An example method stub from Ens.Director
ClassMethod GetProductionStatus(Output pProductionName As %String, Output pState As %Integer...
Trying the normal variable methods
At first glance, you may try the following:
import os
# Set namespace the manual way
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
# TEST 1 with output variables
productionName, productionState = None, None
status = iris.cls('Ens.Director').GetProductionStatus(productionName, productionState)
print("Success? -- {}".format(productionState != None))
But both tests won't return the Output Variables! You can try this yourself on any Ensemble namespace
Using iris.ref
The irispython utility iris.ref
can be used to capture the Output
and ByRef
variables.
- Create an
iris.ref()
object - Call your ObjectScript Method
- Use the
.value
variable to get the result from that parameter
import os
# Set namespace the hard way
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
# TEST 2 with output variables
productionName, productionState = iris.ref('productionName'), iris.ref('productionState')
status = iris.cls('Ens.Director').GetProductionStatus(productionName, productionState)
print("Status: {}".format(status))
# see .value
print("Production: {}".format(productionName.value))
# see .value
print("Production State: {}".format(productionState.value))
Thank you @Nicholai Mitchko for sharing this knowledge !
Addition to the above: Passing Arguments By Referencedoc
Updated link: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...
@Nicholai.Mitchko's example above is Python calling an ObjectScript method that has pass-by-ref arguments, and that works as he described. I wondered if Python methods could be written to return values in their arguments, despite the fact that Python doesn't have pass-by-ref arguments. The answer is "yes," but only if the caller passes in a data structure (like a list or a dict) that the Python method modifies. Otherwise, arguments to a Python method called from either ObjectScript or Python can't return values.
But, if i want to modify the value of the output parameter inside python method, how can i do it?
Thanks
Thank you @Nicholai Mitchko
It is very interesting