Article
· Juil 3, 2023 5m de lecture

Embedded Python, Passage par référence, et Rock & Roll Classic

Les méthodes écrites en ObjectScript peuvent utiliser des arguments de type " passage par référence " pour renvoyer des informations à l'appelant. Python ne supporte pas les arguments de type " passage par référence ", donc Python intégré dans IRIS ne les supporte pas non plus. Voilà, c'est la fin de cet article, j'espère qu'il vous a plu 😉 Mais attendez, et le Rock & Roll Classic ?

En fait, puisque les valeurs retournées dans les arguments de méthode peuvent être utiles, cet article montre plusieurs façons de procéder, entre ObjectScript et Python intégré. Commençons donc par l'exemple le plus simple : l'appel d'une méthode ObjectScript qui dispose déjà d'un argument Python de type " passage par référence ". Voici la méthode :

ClassMethod Sum(a as %Integer, b as %Integer, Output sum as %Integer)
{
    set sum = a + b
}

Il est facile de l'appeler à partir d'ObjectScript. Il vous suffit de ne pas oublier de mettre un "." avant le troisième argument.

USER>set x = 4, y = 5
USER>do ##class(Simple.Demo).Sum(x, y, .z)
USER>write z
9

Mais vous n'êtes pas ici pour cela. Et si vous l'appeliez depuis Python ? Il faut créer un objet de référence spécial en utilisant iris.ref() et le fournir comme troisième argument. Vous ne devez pas placer un "." avant le troisième argument. (Notez que je démarre le shell Python au moyen de :py, un alias pour la fonction do $system.Python.Shell(), une fonction qui mérite un article de la communauté des développeurs pour elle-même).

USER>:py

Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Type quit() or Ctrl-D to exit this shell.
>>> x = 4
>>> y = 5
>>> z = iris.ref(0)
>>> z
<iris.ref object at 0xffff164ca3b0>

>>> iris.cls("Simple.Demo").Sum(x, y, z)
>>> z.value
9

Vous trouverez ici de la documentation sur iris.ref().

Ensuite, examinons quelques façons de permettre à une méthode Python intégré de renvoyer des valeurs dans ses arguments. Pour ces exemples, nous utiliserons des structures JSON qui peuvent être passées dans la méthode et modifiées. Après le retour de la méthode, puisque ces structures sont des références d'objet, toute modification est visible pour l'appelant. Pour JSON, Python supporte les structures dict et list, tandis qu'IRIS supporte les structures %DynamicObject et %DynamicArray. Important : **il n'y a **aucune conversion automatique des structures JSON d'ObjectScript vers les structures JSON de Python (ou vice versa) lorsqu'elles sont passées autour.

Ces options permettent plusieurs combinaisons possibles :

  • À partir de Python, créer un dict ou une liste Python et les passer dans la méthode.
  • À partir d'ObjectScript, créer un dict ou une liste Python et les passer dans la méthode.
  • À partir de Python, créer un %DynamicObject/%DynamicArray IRIS et le passer dans la méthode.
  • À partir d'ObjectScript, créer un %DynamicObject/%DynamicArray IRIS et le passer dans la méthode.

C'est parti pour le rock & roll !

Beatles() est une méthode Python qui renvoie une dict et une liste

/// modifier et renvoyer un dict et une liste
ClassMethod Beatles(membersdict As %SYS.Python, memberslist As %SYS.Python) [ Language = python ]
{
    membersdict['member1'] = 'John'
    memberslist.append('John')
    membersdict['member2'] = 'Paul'
    memberslist.append('Paul')
    membersdict['member3'] = 'George'
    memberslist.append('George')
    membersdict['member4'] = 'Ringo'
    memberslist.append('Ringo')
}

Voici un exemple d'appel à partir de Python :

USER>:py

Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Tapez quit() ou Ctrl-D pour quitter ce shell.
>>> d = {}
>>> l = []
>>> iris.cls("Simple.Demo").Beatles(d, l)
>>> d
{'member1': 'John', 'member2': 'Paul', 'member3': 'George', 'member4': 'Ringo'}
>>> l
['John', 'Paul', 'George', 'Ringo']

Voici un exemple d'appel à partir d'ObjectScript, en passant un dict vide et une liste vide créée en appelant des méthodes de Builtins() :

USER>set d = ##class(%SYS.Python).Builtins().dict()        
USER>set l = ##class(%SYS.Python).Builtins().list()
USER>do ##class(Simple.Demo).Beatles(d, l)
USER>zwrite d
d=7@%SYS.Python  ; {'member1': 'John', 'member2': 'Paul', 'member3': 'George', 'member4': 'Ringo'}  ; <oref>
USER>zwrite l
l=2@%SYS.Python  ; ['John', 'Paul', 'George', 'Ringo']  ; <oref>

Voici quelques documents sur l'utilisation des dicts et des lists à partir d'ObjectScript.

Who() est une méthode Python qui renvoie un %DynamicObject et un %DynamicArray.

/// modifier et renvoyer un %DynamicObject et un %DynamicArray
ClassMethod Who(membersObject As %DynamicObject, membersArray As %DynamicArray) [ Language = python ]
{
    import iris

    membersObject._Set('member1','Roger')
    membersArray._Push('Roger')
    membersObject._Set('member2','Pete')
    membersArray._Push('Pete')
    membersObject._Set('member3','John')
    membersArray._Push('John')
    membersObject._Set('member4','Keith')
    membersArray._Push('Keith')
}

Voici un exemple d'appel à partir de Python, en passant un %DynamicObject vide et un %DynamicArray vide créés en utilisant iris.cls() pour appeler _New(), et en affichant leur contenu à l'aide du %JSON.Formatter :

USER>:py

Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Tapez quit() ou Ctrl-D pour quitter ce shell.
>>> f = iris.cls("%JSON.Formatter")._New()
>>> o = iris.cls("%DynamicObject")._New()
>>> a = iris.cls("%DynamicArray")._New()
>>> o
<iris.%Library.DynamicObject object at 0xffff165c0210>
>>> a
<iris.%Library.DynamicArray object at 0xffff165c0360>
>>> f.Format(o)
{
}
>>> f.Format(a)
[
]
>>> iris.cls("Simple.Demo").Who(o, a)
>>> f.Format(o)
{
  "member1":"Roger",
  "member2":"Pete",
  "member3":"John",
  "member4":"Keith"
}
>>> f.Format(a)
[
  "Roger",
  "Pete",
  "John",
  "Keith"
]

Voici un exemple d'appel à partir d' ObjectScript:

USER>set o = {}, a = []
USER>do ##class(Simple.Demo).Who(o, a)
USER>zwrite o
o={"member1":"Roger","member2":"Pete","member3":"John","member4":"Keith"}  ; <dynamic object="">
USER>zwrite a
a=["Roger","Pete","John","Keith"]  ; <dynamic array="">

Voici quelques documents sur les objets/tableaux dynamiques.

Puisque je vois que certains parmi vous agitent les lumières de leurs téléphones portables d'avant en arrière en demandant un rappel, je vais vous dire une dernière chose : le passage d'un %DynamicObject dans une méthode Python est utile pour une autre raison, qui n'est pas liée au passage par référence. Cela vous permet d'appeler une méthode Python qui accepte des arguments nommés. Lisez tout cela ici !

Discussion (0)0
Connectez-vous ou inscrivez-vous pour continuer