投稿者

インターシステムズジャパン
記事 Toshihiko Minamoto · 10月 25, 2022 8m read

組み込み Python におけるグローバルの使用

私が一番興味を持っているのは、組み込み Python におけるグローバルの使用についてです。
そこで、提供されている公式ドキュメントを確認しました。

#1 グローバルの導入
グローバルとは何かについての一般的な説明。 次の章につながっています。

#2 ObjectScript の詳細について
組み込み Python の記述はありません。
さらに先に進むと...

#3 組み込み Python

3.1 組み込み Python の概要
3.1.1 グローバルの使用

グローバルを使ったことなければ、素晴らしい内容です。
が、驚くほど原始的な例が使われています。
3.2 組み込み Python の使用
最後の望み: >>> でも、目に見えるものが何もありません
残念どころではありません! Python 用の IRIS Native API でさえ、もっと説明されています。
何を期待していたかと言うと...

グローバルノードの SET、GET、KILL

Native API: 基本的なノード操作  そして

$DATA()、$ORDER()、$QUERY() によるナビゲーション

Native API: nextSubscript() と isDefined() によるイテレーション
そこで、自分で調査し、リバースエンジニアリングを行って、実験しなければなりませんでした。

そしてわかったこと:

すべての例は IRIS for Windows (x86-64) 2022.1 (Build 209U) にある Python Shell で説明されており、
暗黙的な print() 関数を集中的に使用している。

グローバル

何をするにも、iris.gref クラスを使って、グローバルの参照オブジェクトを作成することから始める必要があります。
グローバル名は、直接文字列として、またはCOS/ISOS の間接式のように変数として渡されます。
グローバルを扱っていることが明確であるため、最初のキャレット (^) は不要です!

>>> globalname='rcc'

nglob=iris.gref(globalname) glob=iris.gref('rcc') cglob=iris.gref('^rcc')

上記は、同じグローバルへの 3 つのグローバル参照です。
単なる参照であり、このグローバルが存在するかことを示すものではありません。

対話式ドキュメント:  print(glob.doc)
InterSystems IRIS グローバル参照オブジェクト。
グローバルへの参照を取得するには、iris.gref() メソッドを使用します。

 

サブスクリプト

すべてのグローバルサブスクリプトは、Py リストの [sub1,sub2] として渡されます。 COS/ISOS とあまり変わりません。
トップレベルに特別な処理が必要なだけです。
サブスクリプトなしを示すには、空のリストではなく、この [None] を使用します。

SET

グローバルを設定するには、COS/ISOS と同様に「直接」行うことができます。

>>> glob[1,1]=11

または、gref.set() メソッドを使用することもできます。

>>> glob.set([1,3],13)

対話式ドキュメント:  print(glob.set.doc)
グローバルのキーが指定されている場合、グローバルのそのキーに格納された値を設定します。  
例: g.set([i,j], 10) は、グローバル g のキー i,j にあるノードの値を 10 に設定します。

グローバルノードのコンテンツにアクセスするには、COS/ISOS と同様に「直接」行うことができます。

>>> glob[1,3]
13

または、gref.get() メソッドを使用することもできます。

>>> glob.get([1,1])
11

対話式ドキュメント: print(glob.get.doc)
グローバルのキーが指定されている場合、グローバルのそのノードに格納された値を返します。
例: x = g.get([i,j]) は x を、グローバル g のキー i,j に格納された値に設定します。

注意: これは COS/ISOS の $GET() ではありません

>>> glob.get([1,99])
Traceback (most recent call last):
File "", line 1, in <module>
KeyError: 'Global Undefined'

ただし、直接使用すると、COS/ISOS の $GET() のように動作します。

>>> x=glob[1,99]

print(x) None

この None は、SQL が表現するところの NULL を指します。 後で、もう一度出現します。

KILL

期待される結果を達成する gref.kill() メソッドのみがあります。

>>> glob.kill([1,3])

y=glob[1,3] print(y) None

対話式ドキュメント: print(glob.kill.doc)
グローバルのキーが指定されている場合、グローバルのそのノードとサブツリーをキルします。
例: g.kill([i,j]) は、グローバル g のキー i,j に格納されたノードとその子孫ノードをキルします。

$DATA()

関連するメソッドは gref.data() です。
対話式ドキュメント: print(glob.data.doc)
グローバルのキーが指定されている場合、その状態を返します。
例: x = g.data([i,j]) は x を 0、1、10、11 に設定します。
0-if が未定義、1-定義済み、10-未定義で子孫あり、11-値と子孫あり
期待どおりに動作します。

>>> glob.data()
10

glob.data([None]) 10 glob[None]=9 glob.data([None]) 11 glob.data([1,1]) 1 glob.data([1,3]) 0

$ORDER()

この例では、グローバル ^rcc にノードをいくつか追加しました。

>zw ^rcc
^rcc=9
^rcc(1,1)=11
^rcc(1,2)=12
^rcc(2,3,4)=234
^rcc(2,3,5)=235
^rcc(2,4,4)=244
^rcc(7)=7

関連するメソッドは gref.order() です。
対話式ドキュメント: print(glob.order.doc)
グローバルのキーが指定されている場合、そのグローバルの次のキーを返します。
例: j = g.order([i,j]) は j を、グローバル g の次の第 2 レベルのキーに設定します。
つまり、以下のようになります。

>>> print(glob.order([]))
1

print(glob.order([1])) 2 print(glob.order([2])) 7 print(glob.order([7])) None print(glob.order([1,''])) 1 print(glob.order([1,1])) 2 print(glob.order([2,3,])) 4 print(glob.order([2,3,""])) 4 print(glob.order([2,3,4]))
5 print(glob.order([2,4,4])) None

ここでは、参照として欠落しているサブスクリプトまたは空の文字列は同等です。

$QUERY()

関連するメソッドは gref.query() です。
対話式ドキュメント: print(glob.query.doc)
指定されたキーからグローバルをトラバースし、各キーと値をタプルとして返します。
例: for (key, value) in g.query([i,j]) は、キー i,j から g をトラバースし、各キーと値を返します。

このメソッドの動作は COS/ISOS と異なります。

  • 開始ノード以降のすべてのノードを返します。
  • 格納されたコンテンツを含めます。
  • None と示されているコンテンツのない仮想ノードも返します。 ここでの小さな例は、次のようになります(読みやすいように囲んでいます)。

>>> print(list(glob.query()))
[(['1'], None), (['1', '1'], 11), (['1', '2'], 12), (['2'], None),
(['2', '3'], None), (['2', '3', '4'], 234), (['2', '3', '5'], 235),
(['2', '4'], None), (['2', '4', '4'], 244), (['7'], 7)]

もっと読みやすくすると、次のようになります。

>>> for (key, value) in glob.query():
...  print(key,''.ljust(20-len(str(list(key))),'>'),value)
...
['1'] >>>>>>>>>>>>>>> None
['1', '1'] >>>>>>>>>> 11
['1', '2'] >>>>>>>>>> 12
['2'] >>>>>>>>>>>>>>> None
['2', '3'] >>>>>>>>>> None
['2', '3', '4'] >>>>> 234
['2', '3', '5'] >>>>> 235
['2', '4'] >>>>>>>>>> None
['2', '4', '4'] >>>>> 244
['7'] >>>>>>>>>>>>>>> 7

絶対に ZWRITE ではありません!

もう 1 つのオプションは、gref.keys() のみを使用してサブスクリプトを取得する方法です。
対話式ドキュメント: print(glob.keys.doc)
指定されたキーからグローバルをトラバースし、そのグローバルの各キーを返します。
例: for key in g.keys([i, j]) は、キー i,j から g をトラバースし、各キーを返します。 >>>

>>> list(glob.keys())
[['1'], ['1', '1'], ['1', '2'], ['2'], ['2', '3'], ['2', '3', '4'],
['2', '3', '5'], ['2', '4'], ['2', '4', '4'], ['7']]

そして、これで gref.orderiter() を見つけました。
対話式ドキュメント: print(glob.orderiter.doc)
指定されたキーからグローバルをトラバースし、次のキーと値をタプルとして返します。
例: for (key, value) in g.orderiter([i,j]) は、キー i,j から g をトラバースし、次のキーと値を返します。

$QUERY() のようにコンテンツをフェッチして、
そのコンテンツを次のサブノードに提供することも行う $ORDER() のように動作します。
以下を見てください。

>>> list(glob.orderiter([]))
[(['1'], None), (['1', '1'], 11)]

list(glob.orderiter([1])) [(['2'], None), (['2', '3'], None), (['2', '3', '4'], 234)] list(glob.orderiter([2])) [(['7'], 7)]

最後に、gref.getAsBytes() メソッドがあります。
対話式ドキュメント: print(glob.getAsBytes.doc)
グローバルのキーが指定されている場合、そのグローバルのそのノードに格納されている文字列をバイトで返します。
例: x = g.getAsBytes([i,j]) は x をグローバル g のキー i,j に格納されている値をバイトとして設定します。

数値には失敗しますが、 文字列には有効です。

   >>> glob[5]="robert"
   >>> glob.get([5])
   'robert'
   >>> glob.getAsBytes([5])
   b'robert'

また、COS/ISOS で set ^rcc(9)=$lB(99,"robert") を実行すると
以下のようになります。

>>> glob[9]
'\x03\x04c\x08\x01robert'

glob.getAsBytes([9]) b'\x03\x04c\x08\x01robert'

これらのメソッドを以下のようにして検出しました。

>>> for meth in glob.dir():
...  meth
...
'len'
'getitem'
'setitem'
'delitem'
'new'
'data'
'get'
'set'
'kill'
'getAsBytes'
'order'
'query'
'orderiter'
'keys'
'doc'
'repr'
'hash'
'str'
'getattribute'
'setattr'
'delattr'
'lt'
'le'
'eq'
'ne'
'gt'
'ge'
'init'
'reduce_ex'
'reduce'
'subclasshook'
'init_subclass'
'format'
'sizeof'
'dir'
'class'

これで、組み込み Python からグローバルに直接アクセスする必要がある場合に、作業が楽になることを願っています。
個人的に学んだこと: ほとんどの場合に、ドキュメントがあります。 . . . どこにあるかは別ですが。
ただ、探し回る必要があるだけです。

動画デモ

Traduction française

元の記事へ さんが書いた @Robert Cemper