Iijimaさん

ありがとうございます。

--target なしで、パッケージをインストールして、埋め込みPythonで利用できること確認しました。

管理者PowerShell

PS C:\> python -m pip install emoji
Collecting emoji
  Using cached emoji-2.14.1-py3-none-any.whl.metadata (5.7 kB)
Using cached emoji-2.14.1-py3-none-any.whl (590 kB)
Installing collected packages: emoji
Successfully installed emoji-2.14.1
[notice] A new release of pip is available: 24.2 -> 25.0.1
[notice] To update, run: python.exe -m pip install --upgrade pip

PS C:\> python -m site --user-site
C:\Users\imait\AppData\Roaming\Python\Python312\site-packages

PS C:\> python
Python 3.12.7 (tags/v3.12.7:0b05ead, Oct  1 2024, 03:06:41) [MSC v.1941 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import emoji
>>> emoji.emojize('IRIS is :thumbs_up:')
'IRIS is 👍'
>>> emoji.__path__
['C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\emoji']
>>>
>>> import sys
>>> sys.path
['', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\DLLs', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages']

IRIS
 
USER>:py
Python 3.12.7 (tags/v3.12.7:0b05ead, Oct  1 2024, 03:06:41) [MSC v.1941 64 bit (AMD64)] on win32
Type quit() or Ctrl-D to exit this shell.
>>> import emoji
>>> print(emoji.emojize('IRIS is :thumbs_up:'))
IRIS is 👍
>>> emoji.__path__
['C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\emoji']
>>>
>>> import sys
>>> sys.path
['C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\DLLs', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib', 'c:\\intersystems\\iris1\\bin', 'c:\\intersystems\\iris1\\mgr\\python', 'c:\\intersystems\\iris1\\lib\\python', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312', 'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages']
 
IRISの sys.pathは、ネーティブpythonの sys.path の ...\\Lib の後ろに
'c:\\intersystems\\iris1\\bin',
'c:\\intersystems\\iris1\\mgr\\python',
'c:\\intersystems\\iris1\\lib\\python',
が追加されてます。

最初、pythonコマンドとpython3コマンドの違いが分からず、うまく行きませんでした。
python3コマンドは、python V3の場合に常に使うものと勘違いし、パッケージインストールを
PS C:\>python3 -m pip install パッケージ
で行ってました。こうすると、

PS C:\> python3 -m pip install emoji
Defaulting to user installation because normal site-packages is not writeable
Collecting emoji
  Using cached emoji-2.14.1-py3-none-any.whl.metadata (5.7 kB)
Using cached emoji-2.14.1-py3-none-any.whl (590 kB)
Installing collected packages: emoji
Successfully installed emoji-2.14.1

正常にインストールされているようですが
Defaulting to user installation because normal site-packages is not writeable
の表示があり、インストール先は、調べると、...\Lib\site-packages\emoji\ でなく
c:\users\imait\appdata\local\packages\pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0\localcache\local-packages\python312\site-packages\emoji\*
にインストールされていました。このpathを、sys.path にappendしないと、import 出来ません。

当方の環境

PS C:\> python -VV
Python 3.12.7 (tags/v3.12.7:0b05ead, Oct  1 2024, 03:06:41) [MSC v.1941 64 bit (AMD64)]

PS C:\> python3 -VV
Python 3.12.9 (tags/v3.12.9:fdb8142, Feb  4 2025, 15:27:58) [MSC v.1942 64 bit (AMD64)]

(なぜか?)V3が2つあり、私の環境では  python3コマンドの使用は間違いでした。

PS C:\> python -m site
sys.path = [
    'C:\\',
    'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip',
    'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\DLLs',
    'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib',
    'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312',
    'C:\\Users\\imait\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages',
]
USER_BASE: 'C:\\Users\\imait\\AppData\\Roaming\\Python' (doesn't exist)
USER_SITE: 'C:\\Users\\imait\\AppData\\Roaming\\Python\\Python312\\site-packages' (doesn't exist)
ENABLE_USER_SITE: True

PS C:\> python3 -m site
sys.path = [
    'C:\\',
    'C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.12_3.12.2544.0_x64__qbz5n2kfra8p0\\python312.zip',
    'C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.12_3.12.2544.0_x64__qbz5n2kfra8p0\\DLLs',
    'C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.12_3.12.2544.0_x64__qbz5n2kfra8p0\\Lib',
    'C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.12_3.12.2544.0_x64__qbz5n2kfra8p0',
    'C:\\Users\\imait\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python312\\site-packages',
    'C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.12_3.12.2544.0_x64__qbz5n2kfra8p0\\Lib\\site-packages',
]
USER_BASE: 'C:\\Users\\imait\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\\LocalCache\\local-packages' (exists)
USER_SITE: 'C:\\Users\\imait\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python312\\site-packages' (exists)
ENABLE_USER_SITE: True
PS C:\>

余談ですが、Pyhon自身のバージョン管理、使うパッケージのバージョン管理(場所)は、格好悩ましいですね。

ちなみに、Pythonネーティブ環境で、sys.path に sys.path.append('c:/intersystems/iris1/mgr/python') すると、IRISに落としたパッケージも使えるようです。

また、逆に、管理ポータル システム > 構成 > メモリ詳細設定 > メモリ設定編集 > PythonPath に追加path(複数指定可)を指定すると、埋め込みPython の sys.path の 'c:/intersystems/iris1/lib/python' の 後ろ!!に追加され、パッケージの別管理も出来るようです。

Iijimaさん

ありがとうございます。Python Load 成功しました。

追加で質問です。

Pythonパッケージのインストール(アップグレード)方法とその場所について

IRIS 2024.2からirispipコマンドもなくなっているようでね。

第2回-開発者コミュニティ・ミートアップ より例:
pip3 install flask

マニュアルより
Install Python Packages on Windows
https://docs.intersystems.com/iris20243/csp/docbook/DocBook.UI.Page.cls?...
On Windows, the irispip command was removed in InterSystems IRIS 2024.2. 
On Windows, use the command python -m pip install --target <installdir>\mgr\python <package>.

それで、インストールコマンドは

python3 -m pip install --target <installdir>\mgr\python <package>
または
pip3 install --target <installdir>\mgr\python <package>

が正解ですか?
--target は省略可能ですか?(その場合、パッケージの保存場所や埋め込みPythonでの利用は?)

ちなみに、Python3.12 標準インストール後も、以前、irispipでインストールしていたパッケージは一応動いているようです。

以下は、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>

はじめまして、こんな方法は如何ですか?

出来るだけ、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>