Bridging the Gap Between ObjectScript and Embedded Python
Because of the differences between the ObjectScript and Python languages, you will need to know a few pieces of information that will help you bridge the gap between the languages.
From the ObjectScript side, the %SYS.PythonOpens in a new tab class allows you to use Python from ObjectScript. See the InterSystems IRIS class reference for more information.
From the Python side, the iris module allows you to use ObjectScript from Python. From Python, type help(iris) for a list of its methods and functions, or see InterSystems IRIS Python Module Reference for more details.
InterSystems IRIS has the concept of namespaces, each of which has its own databases for storing code and data. This makes it easy to keep the code and data of one namespace separate from the code and data of another namespace. For example, if one namespace has a global with a certain name, another namespace can use a global with the same name without the danger of conflicting with the other global.
If you have two namespaces, NSONE and NSTWO, you could create a global called ^myFavorite in NSONE, using ObjectScript in Terminal, as shown below. Then you could set the $namespace special variable to change to NSTWO and create a separate global called ^myFavorite in that namespace. (To replicate this example, you can configure these two namespaces on your InterSystems IRIS instance or use two namespaces you already have.)
NSONE>set ^myFavorite("fruit") = "apple"
NSONE>set $namespace = "NSTWO"
NSTWO>set ^myFavorite("fruit") = "orange"
Here, ^myFavorite("fruit") has the value "apple" in NSONE and the value "orange" in NSTWO.
When you call Embedded Python, it inherits the current namespace. We can test this by calling the NameSpace() method of the %SYSTEM.SYSOpens in a new tab class from Python, which displays the name of the current namespace, and by confirming that ^myFavorite("fruit") = "orange".
Python 3.9.5 (default, Jun 2 2023, 14:12:21) [MSC v.1927 64 bit (AMD64)] on win32
Type quit() or Ctrl-D to exit this shell.
>>> myFav = iris.gref('^myFavorite')
You’ve seen how to use $namespace to change namespaces in ObjectScript. In Embedded Python, you use the SetNamespace() method of the iris.system.Process class. For example, you can change to the namespace NSONE and confirm that ^myFavorite("fruit") = "apple".
>>> myFav = iris.gref('^myFavorite')
Finally, when you exit from the Python shell, you remain in namespace NSONE.
Running an ObjectScript Command from Embedded Python
There are times you may want to run an ObjectScript command from Embedded Python, for example, to access a system-provided “special variable”, to call a routine written in ObjectScript, or to perform other tasks where there is no available method to call. In such cases, you can use the methods iris.execute() and iris.routine() from Python.
The following example writes the special variable $zversion, which contains the InterSystems IRIS version string:
>>> iris.execute("write $zversion,!")
IRIS for Windows (x86-64) 2022.3 (Build 602U) Mon Jan 23 2023 14:05:04 EST
Sometimes you may want to return a value from iris.execute() and assign it to a Python variable. This example assigns the value of the special variable $horolog, which contains the local date and time for the current process in InterSystems IRIS internal storage format, to the variable t:
>>> t = iris.execute("return $horolog")
This is equivalent to t = iris.cls('%SYSTEM.SYS').Horolog(), which uses the Horolog() method of the class %SYSTEM.SYSOpens in a new tab.
You may encounter older ObjectScript code that uses routines instead of classes and methods and want to call a routine from Embedded Python. If you have a routine ^Math that has a function Sum() that returns the sum of two numbers, you can add two numbers and assign the return value to the Python variable sum, as follows:
>>> sum = iris.execute("return $$Sum^Math(4,3)")
While the recommended way to access globals from Embedded Python is to use the iris.gref() method, you can also set and retrieve values from a global by using iris.execute(). The following example sets the global ^motd to the value "hello world" and then retrieves the value from the global.
>>> iris.execute("set ^motd = \"hello world\"")
>>> iris.execute("return ^motd")
You can also call routines by using the iris.routine() method. The following example, when run in the %SYS namespace, calls the routine ^SECURITY:
1) User setup
2) Role setup
3) Service setup
4) Resource setup
The example given above of calling the Sum() function of a hypothetical ^Math routine can also be done with the iris.routine() method. The following example adds the numbers 4 and 3:
>>> sum = iris.routine('Sum^Math',4,3)