記事
· 2024年9月12日 3m read

PythonからIRISルーチンに引数を渡すサンプル

これは InterSystems FAQ サイトの記事です。
 

PythonからObjectScriptのルーチンを直接呼び出すことはできませんが、クラスメソッドを経由して間接的に呼び出すことができます。

しかし、Pythonの変数とObjectScriptのローカル変数は内部構造が異なるため、情報の交換には少し工夫が必要です。

簡単なサンプルでその方法について説明します。

まず、2つの変数を足し算する簡単なルーチン ^testを作ります。 

 

TEST    ;
    set sum = a + b

 

次にこの^testを呼び出すPythonのメソッドを含んだUser.testというクラスを作ります。

そしてpyという名前のPythonのメソッドを作成します。

先述の通りPythonからObjectScriptのルーチンを直接呼び出すことはできないので、ルーチンを間接的に呼び出すObjectScriptのメソッドを作成する必要があり、そのメソッドをPythonメソッドから呼び出すようにします。

渡したいデータが複数個ある場合、その数分引数を用意するのは面倒なため、Pythonの場合、情報をまとめて交換する際にdictionary(辞書)やlistという構造を使用することができます。

ここでは、dictionaryを使用する例を紹介します。

ClassMethod py() [ Language = python ]

{

   import iris

   rtn = "^test"
#  変数argのdictionary構造にa = 10, b = 20を設定
   arg = {"a":10, "b":20}

   ret = iris.cls('User.test').callrtn(rtn, arg)

# 戻り値のdictionary変数retにローカル変数sumの値が設定されている   
   print (ret.get("sum"))

}

 

次にルーチンを呼び出すためのクラスメソッドを定義します。

PythonのDictionary構造をObjectScriptで操作するためには、少し特別な処理が必要です。

ClassMethod callrtn(rtnname As %String, plist As %String) As %Integer [ ProcedureBlock = 0 ]

{
    // python dictから変数を取得
    set a = plist."get"("a")
    set b = plist."get"("b")
    
   // 2. ルーチンを実行する
   do @rtnname

   // 3. ローカル変数 ==> 戻り値 (python dict)
   kill rtnname,plist

   set ret = ##class(%SYS.Python).Builtins().dict()

   // 存在するローカル変数からdictionaryを生成する    set %="%"
   for {
       // ローカル変数を順番に取得
       set %=$Order(@%)

       quit:%=""        
       //変数retは除く
       continue:%="ret"
       do ret.setdefault(%, @%)

   }

   quit ret

}

 

2023.2以降のバージョンではarrayrefのサポートが追加されており、より直感的な処理が可能になりました。

 

ClassMethod py() [ Language = python ]
{
    import iris
    rtn = "^test"
    arg = {"a":10, "b":20}
    ar = iris.arrayref(arg)
    ret = iris.cls('Test.pytest').callrtn(rtn,ar)

    print (ret.get("sum"))
}

 

ClassMethod callrtn(rtnname As %String, plist As %String) As %Integer [ ProcedureBlock = 0 ]
{

    set a = plist("a")
    set b = plist("b")

    // ルーチン実行
    do @rtnname

    //ローカル変数 ==> 戻り値(python dict)
    kill rtnname, plist
    set ret = ##class(%SYS.Python).Builtins().dict()
    set % = "%"
    for {
        set %=$order(@%)
        quit:%=""
        continue:%="ret"
        do ret.setdefault(%, @%)
    }
    quit ret
}
ディスカッション (0)1
続けるにはログインするか新規登録を行ってください