ユーザーの略歴
404 経歴が見つかりません
2023年4月24日からのメンバー
投稿:
返信:
はじめまして、こんな方法は如何ですか?
出来るだけ、ObjectScript、Python、それぞれで、自身のデータ型で処理できるように、渡す前後で、相手のタイプに変換/逆変換出来れば、透過性がよくなるかもしれません。
Class Py.Demo Extends %RegisteredObject
{
/// d ##Class(Py.Demo).Test()
ClassMethod Test()
{
set builtins = ##class(%SYS.Python).Builtins()
set json = ##class(%SYS.Python).Builtins().Import("json")
;# ObjectScritタイプ
set oslist=[1.23456789012345678901234,true,false,null,0,1,"","英語"]
set osdict={"A":33,"a":"lower case","漢字":"日本"}
set osdict.list=oslist
;# Pythonタイプに変換
set pydict = builtins.dict() ;この行余計かも
set pydict = json.loads(osdict.%ToJSON())
set pylist = builtins.list() ;この行余計かも
set pylist = json.loads(oslist.%ToJSON())
zw builtins.type(pydict)
zw builtins.type(pylist)
;# Pythonタイプで引数参照で渡す
;# *******************
set ret = ##Class(Py.Demo).PythonProc( pydict , pylist )
;# *******************
;# 参照引数渡しなので、結果として、Python側で変更された値が、引数に反映される
;# ObjectScript型に戻す
set osdict = {}.%FromJSON(..jsondumps(pydict))
set oslist = [].%FromJSON(..jsondumps(pylist))
#; 以下でも jsondumps 使わず、文字化けは解消します
#;set osdict= {}.%FromJSON($zcvt($zcvt(json.dumps(pydict),"I","JS"),"I","JSON"))
#;set oslist= [].%FromJSON($zcvt($zcvt(json.dumps(pylist),"I","JS"),"I","JSON"))
w !,osdict.UPDATE
w !,oslist."0"
w !
#; 返値も、構造が分かれば、Pythonの組み込み関数を利用して分解し、ObjectScript型に変換
#; return タプル( dict , list ) を前提
set retdict = {}.%FromJSON(..jsondumps(ret."__getitem__"(0)))
set retlist = [].%FromJSON(..jsondumps(ret."__getitem__"(1)))
w !
zw retdict
w !
zw retlist
}
ClassMethod jsondumps(str) As %SYS.Python [ Language = python ]
{
#; 文字化け対応のキーワード指定(ensure_ascii=False)
#; ObjectScritで、キーワード引数指定の仕方が分からないので python クラスにする
import json
return json.dumps(str,ensure_ascii=False)
}
ClassMethod PythonProc(dict As %SYS.Python, list As %SYS.Python) As %SYS.Python [ Language = python ]
{
#; Python側では、自身のデータタイプでアクセス
import json
print(type(dict))
print(dict)
print(type(list))
print(list)
dict['UPDATE']='dict Python側で変更しました'
list[0]='list ここも変更しました'
return ( dict , list )
}
}
処理結果
USER>d ##Class(Py.Demo).Test()
6@%SYS.Python ; <class 'dict'> ; <OREF>
6@%SYS.Python ; <class 'list'> ; <OREF>
<class 'dict'>
{'A': 33, 'a': 'lower case', '漢字': '日本', 'list': [1.2345678901234567, True,False, None, 0, 1, '', '英語']}
<class 'list'>
[1.2345678901234567, True, False, None, 0, 1, '', '英語']
dict Python側で変更しました
list ここも変更しました
retdict={"A":33,"a":"lower case","漢字":"日本","list":[1.2345678901234567,true,false,null,0,1,"","英語"],"UPDATE":"dict Python側で変更しました"} ; <DYNAMIC OBJECT>
retlist=["list ここも変更しました",true,false,null,0,1,"","英語"] ; <DYNAMIC ARRAY>
USER>
認定証と Credly バッジ:
imaさんはまだ認定証と Credly バッジを取得していません.
Global Mastersバッジ:
imaさんはグローバルマスターズバッジをまだ取得していません。
フォロワー:
imaさんにはまだフォロワーがいません。
フォロー中:
imaさんはまだ誰もフォローしていません。
以下は、PythonからObjectScriptを呼び出す場合のJSONデータの渡し方のサンプルです。
Class Py.Demo2 Extends %RegisteredObject { /// d ##Class(Py.Demo2).Test() /// PythonからObJectScriptを呼び出す場合のJSONデータの渡し方案 /// ObJectScriptを呼び出す前後で、Python型からObJectScript型に変換/逆変換する ClassMethod Test() [ Language = python ] { import iris import json list = [1.23456789012345678901234,True,False,None,0,1,''] dict = {'A':33,'a':'lower case','漢字':'日本'} dict['list'] = list #; ObjectScript型へ変換 osdict = iris.cls("%DynamicObject")._New()._FromJSON(json.dumps( dict , ensure_ascii=False )) oslist = iris.cls("%DynamicArray")._New()._FromJSON(json.dumps( list , ensure_ascii=False )) print(f'type(osdict) = {type(osdict)}') print(f'osdict = {osdict._ToJSON()}') print(f'type(oslist) = {type(oslist)}') print(f'oslist = {oslist._ToJSON()}') arg = iris.ref("引数参照渡し") print(f'type(arg)={type(arg)}') arf = iris.arrayref(dict) #; アレイ参照渡し dictのみでlistはエラー print(f'type(arf)={type(arf)}') print('ObjectScript Proc 呼出し') #;**************************** ret = iris.cls("Py.Demo2").OSProc( osdict , oslist , arg , arf ) #;**************************** print('ObjectScript Proc 終了') print(f'返値型 = {type(ret)}') print(f'返値 = {ret}') #; Python型へ変換 dict = json.loads(osdict._ToJSON()) list = json.loads(oslist._ToJSON()) print(type(dict)) print(dict) print(type(list)) print(list) print(f'arg.value={arg.value}') iris.execute('zw ^||TEST') ;#ネストはなし(dict['list']) #: 以下の iris.gref は、^||...はエラーになるのでNOP #; g = iris.gref('^||TEST') #; for key in g.keys([]): #; value = g[key] #; print(f'{key} = {value}') } ClassMethod OSProc(ByRef Obj As %DynamicObject, ByRef Arr As %DynamicObject, ByRef Arg, ByRef Arf) As %DynamicAbstractObject { s Obj.UPDATE="dict Python側で変更しました" s Arr."0"="list ここも変更しました" s Arg=Arg_" 追加しました" w !,"Obj=",Obj.%ToJSON() w !,"Arr=",Arr.%ToJSON() w ! zw Arf k ^||TEST m ^||TEST=Arf w !,"プロセス・プライベート・グローバル ^||TEST にセットしました",! q "Ok" #; dict で返す場合 #; s json = ##class(%SYS.Python).Builtins().Import("json") #; s dict = json.loads(Obj.%ToJSON()) #; q dict } }
実行結果
USER>d ##Class(Py.Demo2).Test() type(osdict) = <class 'iris.%Library.DynamicObject'> osdict = {"A":33,"a":"lower case","漢字":"日本","list":[1.2345678901234567,true,false,null,0,1,""]} type(oslist) = <class 'iris.%Library.DynamicArray'> oslist = [1.2345678901234567,true,false,null,0,1,""] type(arg)=<class 'iris.ref'> type(arf)=<class 'iris.arrayref'> ObjectScript Proc 呼出し Obj={"A":33,"a":"lower case","漢字":"日本","list":[1.2345678901234567,true,false,null,0,1,""],"UPDATE":"dict Python側で変更しました"} Arr=["list ここも変更しました",true,false,null,0,1,""] Arf("A")=33 Arf("a")="lower case" Arf("list")=4@%SYS.Python ; [1.2345678901234567, True, False, None, 0, 1, ''] ; <OREF> Arf("漢字")="日本" プロセス・プライベート・グローバル ^||TEST にセットしました ObjectScript Proc 終了 返値型 = <class 'str'> 返値 = Ok <class 'dict'> {'A': 33, 'a': 'lower case', '漢字': '日本', 'list': [1.2345678901234567, True, False, None, 0, 1, ''], 'UPDATE': 'dict Python側で変更しました'} <class 'list'> ['list ここも変更しました', True, False, None, 0, 1, ''] arg.value=引数参照渡し 追加しました ^||TEST("A")=33 ^||TEST("a")="lower case" ^||TEST("list")="4@%SYS.Python" ^||TEST("漢字")="日本" USER>