埋め込みPythonは、同じプロセス空間で、IRIS言語とPython言語を組み合わせて使える面白い環境を提供しますが、組み合わせて使う場合、オブジェクトタイプとそのアクセス方法の違いをはっきり意識して使わないと混乱するように思います。その使い分けの勉強の為、両言語のオブジェクト参照から、その構造を解析ダンプするツールを作ってみました。とくに、実行中のPython情報が、ZWRITE Oref コマンドでの表示しかないようなので、有用かも知れません。ツールは、まだ、間違い、改良等があると思います(教えて下さい)が、ポストします。
ツール本体: Py.Dump.cls
Class Py.Dump Extends %RegisteredObject
{
/// Py.Dump.cls
/// ObjectScript 及び Python のオブジェクトデータ解析ツール(ダンパー)
/// 入力:ObjectScript 及び 埋め込みPython のデータオブジェクト参照 Oref
/// 出力: 端末と指定グローバル/ローカル変数(デフォルトは ^||o)に Oref のデータ構造を解析し出力する
/// 変数には、データタイプの木構造がセットされる
/// 呼び出し:
/// >d ##Class(Py.Dump).o(oref) 出力グローバルは ^||o
/// >d ##Class(Py.Dump).o(oref,"...") ... は出力グローバル/ローカル変数名(初期Killされる)
/// >d ##Class(Py.Dump).o(oref,"") 結果変数出力 zw @gbl は実行しない (^||o はセットされる)
/// or
/// 簡易エントリールーチン : Py.Dump.mac
/// >d o^Py.Dump(oref)
/// >d o^Py.Dump(oref,"")
/// >d o^py.Dump(oref,"o")
/// >d o^Py.Dump(oref,"^ABC")
/// >d o^Py.Dump({"a":2,"B":"漢字"},"")
///
/// サンプル実行 : サンプルデータクラス Py.Sample.cls 利用
/// >d s^Py.Dump(i) i=1,2... i は Py.Sample.cls のクラスメソッド si
ClassMethod o(oref, gbl)
{
If '$DATA(oref) Quit
Set NoZwGbl=0
If $DATA(gbl)#10=1,gbl="" {
Set NoZwGbl=1 ; O(oref,"") の場合、^||o にセットするが、最後の zw @gbl なし
}
If $GET(gbl)="" {
Set gbl= "^||o" ; デフォルト出力グローバル
}
If gbl'?.1"^".1"||"1(1"%",1A).AN Write !,"変数名 ",gbl," 指定エラー" Quit
Kill @gbl
Write !
Do NextOref(oref,0,.gbl)
If 'NoZwGbl Write !!! ZWrite @gbl Write !
}
ClassMethod NextOref(oref, level = 0, gbl) [ Private ]
{
If '$DATA(oref) Quit
If '$DATA(%builtins) Set %builtins = ##class(%SYS.Python).Builtins()
If '$DATA(%json) Set %json = %builtins.Import("json")
If '$ISOBJECT(oref) {
Set @gbl=oref
Do ..NonObject(oref,gbl)
Quit
}
Set classname=$CLASSNAME(oref)
If classname="%SYS.Python"
{
Set type=..PythonType(oref)
Set iterable=%builtins.hasattr(oref,"__iter__")
If iterable {
Set repr=%builtins.repr(oref)
Write type,":",repr
Set @gbl=type_":"_repr
Set iskeys=%builtins.hasattr(oref,"keys")
If iskeys { ; key-value type
/// dict
Do ..Property(oref,level,gbl,type)
Do ..Method(oref,level,gbl,type)
Set iter=oref."__iter__"()
Set len=oref."__len__"()
For i=0:1:len-1 {
Set key2=iter."__next__"()
Set oref2=oref."__getitem__"(key2)
Set type2=..PythonType(oref2)
Write !?level*4,type,"(""",key2,""") = "
Set gbl2=$NAME(@gbl@(type,key2))
If $ISOBJECT(oref2) {
Do ..NextOref(oref2,level+1,gbl2)
}
Else {
Do ..NonObject(oref2,gbl2,type2)
}
}
}
Else {
/// tuple,list,set,range,bytearray
Do ..Property(oref,level,gbl,type)
Do ..Method(oref,level,gbl,type)
Set iter=oref."__iter__"()
Set len=oref."__len__"()
Set @gbl@(type)=len
For i=0:1:len-1 {
Set oref2=iter."__next__"()
Set type2=..PythonType(oref2)
Write !?level*4,type,"(",i,") = "
Set gbl2=$NAME(@gbl@(type,i))
If $ISOBJECT(oref2) {
Do ..NextOref(oref2,level+1,gbl2)
}
Else {
Do ..NonObject(oref2,gbl2,type2)
}
}
}
}
Else {
Set repr=%builtins.repr(oref)
Write type,":",repr
Set @gbl@(type)=type_":"_repr
Do ..Property(oref,level,gbl,type)
Do ..Method(oref,level,gbl,type)
}
}
ElseIf classname="%Library.DynamicArray" {
Set type="array"
Try {
Set json=oref.%ToJSON()
}
Catch e {
Set json="%ToJSON変換エラー:"_e.Name
}
Write type,":",json
Set @gbl=type_":"_json
Set size=oref.%Size()
Set @gbl@(type)=size
For i=0:1:size-1 {
Write !?level*4,type,"(",i,") = "
Set oref2=oref.%Get(i)
Set type2=oref.%GetTypeOf(i)
Set gbl2=$NAME(@gbl@(type,i))
If $ISOBJECT(oref2) {
Do ..NextOref(oref2,level+1,gbl2)
}
Else {
Do ..NonObject(oref2,gbl2,type2)
}
}
}
ElseIf classname="%Library.DynamicObject" {
Set type="object"
Try {
Set json=oref.%ToJSON()
}
Catch e {
Set json="%ToJSON変換エラー:"_e.Name
}
Write type,":",json
Set @gbl=type_":"_json
Set iter = oref.%GetIterator()
While iter.%GetNext(.key2, .value2, .type2 ) {
Write !?level*4,type,"(""",key2,""") = "
Set gbl2=$NAME(@gbl@(type,key2))
If $ISOBJECT(value2) {
Do ..NextOref(value2,level+1,gbl2)
}
Else {
Do ..NonObject(value2,gbl2,type2)
}
}
}
Else {
; その他のクラス
Write !?level*4,"Class : ",oref.%ClassName(1),!
Do DumpObject^%apiOBJ(oref)
;w ! zw oref w !
}
}
ClassMethod PythonType(oref)
{
;# Pythonのデータタイプを返す
If '$DATA(%builtins) Set %builtins = ##class(%SYS.Python).Builtins()
Quit %builtins.type(oref)."__name__"
}
ClassMethod NonObject(value, gbl, type = "") [ Private ]
{
If value'="",$LISTVALID(value) {
#; $list(...)
Write "$list:",$LISTTOSTRING(value,,1)
Set @gbl@("$list")=value
}
#; ObjectScript number,string,boolean,null,unssingned
#; Python bool,date,datetime,float,int,str
Else {
If $GET(type)="" Set type=$SELECT(value=+value:"numeric",1:"string")
Write type,":",value
Set @gbl=type_":"_value
}
}
ClassMethod Property(oref, level, gbl, type) [ Private ]
{
Set properties=..GetProperties(oref)
For i=0:1:properties."__len__"()-1 {
Set prop=properties."__getitem__"(i)
Set oref2=%builtins.getattr(oref,prop)
Set type2=..PythonType(oref2)
Write !?level*4,type," .",prop," = "
Set gbl2=$NAME(@gbl@(type,"."_prop))
If $ISOBJECT(oref2) {
Set repr=%builtins.repr(oref2)
Write type2,":",repr
Set @gbl2@(type2)=repr
#; datetime の場合、prop="max" で $isobject(oref2)=1 になり、
#; do NextOref(oref2,level+1,gbl2)
#; で、オブジェクト展開の再帰呼び出しをすると、なぜか同じ oref が現れ
#; __getattr__が再帰呼び出されて、再帰無限ループになる ?
#; それで、Property値のネスト展開は NOP にする
#; Property値は、Property名が分かれば、oref.Property名 で取れる
}
Else {
Do ..NonObject(oref2,gbl2,type2)
}
}
}
ClassMethod Method(oref, level, gbl, type) [ Private ]
{
Set methods=..GetMethods(oref)
Set len=methods."__len__"()
If len=0 Quit
If 1 { ;# リスト表示
Set repr=%builtins.repr(methods)
Write !?level*4,"methods:",repr
Set @gbl@(type,"methods")=repr
}
Else { ;# 展開表示
For i=0:1:len-1 {
Set method=methods."__getitem__"(i)
Set oref2=%builtins.getattr(oref,method)
Set type2=..PythonType(oref2)
Write !?level*4,type," .",method,"() = "
Set gbl2=$NAME(@gbl@(type,"."_method_"()"))
Set repr=%builtins.repr(oref2)
Write type2,":",repr
Set @gbl2=type2_":"_repr
}
}
}
ClassMethod GetProperties(oref) [ Language = python ]
{
properties = [ prop for prop in dir(oref) if not callable(getattr(oref, prop)) and not prop.startswith('__')]
return properties
}
ClassMethod GetMethods(oref) [ Language = python ]
{
methods = [method for method in dir(oref) if callable(getattr(oref, method)) and not method.startswith('__')]
return methods
}
ClassMethod GetAttributes(oref) [ Language = python ]
{
attributes = [attr for attr in dir(oref) if not attr.startswith('__')]
return attributes
}
}
簡易・テストエントリー:Py.Dump.mac
ROUTINE Py.Dump
#; Py.Dump
#; ObjectScript 及び Python のオブジェクトデータ解析ダンプ(Py.Dump.cls)簡易エントリー
#; d o^Py.Dump(oref) ^||o にセット
#; d o^Py.Dump(oref,"^...") グローバル変数 ^... にセット
#; d o^Py.Dump(oref,"...") ローカル変数 ... にセット
#; d o^Py.Dump(oref,"") ^||o にセットするが結果表示 zw ^||o はしない
o(oref,&gbl)
Do ##Class(Py.Dump).o(oref,.gbl)
Quit
#; サンプル実行
#; d s^Py.Dump(i) i=1,2... Py.Sampleクラスの メソッド Si
#; d s^Py.Dump(i,"")
#; d s^Py.Dump(i,"^A")
#; d s^Py.Dump(i,"o")
s(i,gbl) ;
Try {
Set oref=$CLASSMETHOD("Py.Sample","s"_i)
Do o(oref,.gbl)
}
Catch {
Write !,$ZERROR
}
Quit
; d t^Py.Dump
t ; 埋め込みPythonコード例(実験)
Kill
Set builtins = ##class(%SYS.Python).Builtins()
Set json = builtins.Import("json")
Set oref=builtins.dict()
Do oref."__setitem__"("日本","富士山") ; s oref.日本="富士山" は使えないので
Do oref."__setitem__"("山",1122) ; 組み込み関数 __setitem__ の _ が結合演算子になるので使えないため、奇異だが "__...__" が必要
Do oref.setdefault("川",567)
ZWrite oref ; zw oref だと変数に取れない
Set d=builtins.repr(oref)
Write !,"builtins.repr(oref)=",d ;変数に取れるが表示形式
ZWrite builtins.type(oref) ;zw だと Python type が正確に(変数に)取れない
Set class=builtins.type(oref)."__class__"
Set type=builtins.type(oref)."__name__"
Write !,"class=",class," type=",type ;type取得
; zwrite oref の表示しか、Python情報を取れないのがとても不便 ! => ダンプツールが欲しい
Write !,"ダンプツール"
Do o^Py.Dump(oref,"")
; zw oref では、%SYS.Pythonクラスであることぐらいしか情報が得られないが
; 以下の情報は、どの oref でも利用出来、有用です
ZWrite builtins.dir(oref) ;これも Zw oref !!
ZWrite builtins.help(oref)
; zw を使わず、プログラムで情報を得るには...
Set help=builtins.repr(builtins.dir(oref))
Write !,help
; builtins.dir(oref) は Python listタイプ なので...
Set list=builtins.dir(oref)
Write !!,"Python list ループ",!
Set iter=list."__iter__"() For i=0:1:list."__len__"()-1 Write:i'=0 " , " Write iter."__next__"()
; ObjectScriptの array に変換したほうが簡単か
Set args={"ensure_ascii": 0},array = [].%FromJSON(json.dumps(list,args...))
Write !,"ObjectScript Array ループ",!
For i=0:1:array.%Size()-1 Write:i'=0 " , " Write array.%Get(i)
; oref の属性(Property,Method)を知りたい、変数に
Write !,"Properties list = "
Set Properties=##Class(Py.Dump).GetProperties(oref) ;Python listタイプ
Do builtins.print(Properties)
Write !,"Methods list = "
Set Methods=##Class(Py.Dump).GetMethods(oref)
Do builtins.print(Methods)
Write !,"builtins oref ダンプ"
Do o^Py.Dump(builtins,"")
Write !,"json oref ダンプ"
Do o^Py.Dump(json,"")
; 感想
; %SYS.Python クラスから派生したすべてのオブジェクト参照の処理は、Python言語に頭の切り替えが必要かと
; どこまで、ObjectScriptコード と Pythonコード を混在させて書くか? あるいは、Pyファイル経由や
; ObjectScriptコード <-> Python 呼び出しでタイプ変換して、疎結合で組むか ?
; デバッグ、メンテ等を考えて要判断か...
Quit
テストサンプル:Py.Sample.cls
Class Py.Sample Extends %RegisteredObject
{
/// Py.Sample.Cls
/// クラス Py.Dump.cls のテストサンプル
/// ルーチン Py.Dump.mac で使う
ClassMethod s1() As %SYS.Python [ Language = python ]
{
#; Pythonタイプ
from datetime import datetime, date
sample_dict = {
"整数": 42,
"浮動小数点数": 3.14159,
"文字列": "こんにちは、世界!",
"リスト": [1, 2, "三"],
"タプル": (7, "八", "九"),
"辞書": {"キー1": "値1", "キー2": "値2"},
"集合": {1, 2,frozenset(["一", "二"])},
"ブール値": True,
"None": None,
"レンジ": range(0,2,20),
"タプル":("山","川","谷"),
"バイトアレイ": bytearray(b'example bytearray'), # bytearray
"バイト": b'example bytes', # bytes
"日時": datetime.now(),
"日付": date.today(),
'混合':[1, 2, 3,['四', '五',{'内部辞書1': '六','タプル':(8, 9, ('七', '八', {'さらに内部辞書': '九'}))}]]
}
return sample_dict
}
ClassMethod s2() As %DynamicAbstractObject
{
;# ObjectScritタイプ
Set sample={
"オブジェクト":{"A":33,"a":"lower case","漢字":"日本"},
"アレイ":[1.23456789012345678901234,true,false,null,0,1,"","英語"],
"混合":{"A":"一","B":["二","三",{"四":4,"五":5},"六"],"C":"八"}
}
Quit sample
}
ClassMethod s3() As %DynamicAbstractObject
{
Set mix={ "Python dict":(..s1()) , "ObjectScript object":(..s2()) }
Quit mix
}
ClassMethod s4() As %SYS.Python [ Language = python ]
{
import iris
mix= {"Python dict":iris.cls("Py.Sample").s1(), "ObjectScript object":iris.cls("Py.Sample").s2()}
return mix
}
ClassMethod s5() As %SYS.Python [ Language = python ]
{
return (True,False,None)
}
ClassMethod s6() As %DynamicAbstractObject
{
Set a=[] ;#ObjectScript の array
Set a."0"=##class(%SYS.Python).True() ;#中は Python type
Set a."1"=##class(%SYS.Python).False()
Set a."2"=##class(%SYS.Python).None()
Quit a
}
ClassMethod s7() As %SYS.Python [ Language = python ]
{
import iris
import json
pydict = {'A':33,'a':'lower case','漢字':'日本'}
#; ObjectScript型へ変換
osdict = iris.cls("%DynamicObject")._New()._FromJSON(json.dumps( pydict , ensure_ascii=False ))
mixed_dict = {"pydict":pydict, "osdict":osdict}
return mixed_dict
}
ClassMethod s8() As %SYS.Python [ Language = python ]
{
return b'Hello Bytes!'
}
ClassMethod s9() As %DynamicAbstractObject
{
Quit ##class(%SYS.Python).Bytes("Hello Bytes!")
}
ClassMethod s10() As %SYS.Python [ Language = python ]
{
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"こんにちは、私の名前は {self.name} で、{self.age} 歳です。"
person1 = Person("山田", 30)
person2 = Person("上田", 25)
print(person1.greet())
print(person2.greet())
return (person1, person2)
}
ClassMethod s11() As %SYS.Python [ Language = python ]
{
class CustomCollection:
def __init__(self, elements=None):
if elements is None:
elements = []
self.elements = elements
def __len__(self):
return len(self.elements)
def add(self, element):
self.elements.append(element)
def remove(self, element):
if element in self.elements:
self.elements.remove(element)
else:
raise ValueError(f"Element {element} not found in collection.")
def find(self, element):
return element in self.elements
def __str__(self):
return f"CustomCollection with elements: {self.elements}"
my_collection = CustomCollection([1, 2, 3, 4, 5])
my_collection.add(6)
print(my_collection)
my_collection.remove(3)
print(my_collection)
print(my_collection.find(2))
print(my_collection.find(3))
print(len(my_collection))
return my_collection
}
}
実行例 入力 oref は Py.Sample.cls の メソッド s1 と s10 の返り値
USER>D s^Py.Dump(1)
dict:{'整数': 42, '浮動小数点数': 3.14159, '文字列': 'こんにちは、世界!', 'リスト': [1, 2, '三'], 'タプル': ('山', '川', '谷'), '辞書': {'キー1': '値1', 'キー2': '値2'}, '集合': {frozenset({'二', '一'}), 1, 2}, 'ブール値': True, 'None': None, 'レンジ': range(0, 2, 20), 'バイトアレイ': bytearray(b'example bytearray'), 'バイト': b'example bytes', '日時': datetime.datetime(2024, 7, 20, 9, 47, 50, 200660), '日付': datetime.date(2024, 7, 20), '混合': [1, 2, 3, ['四', '五', {'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}]]}
methods:['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
dict("整数") = int:42
dict("浮動小数点数") = float:3.141589999999999883
dict("文字列") = str:こんにちは、世界!
dict("リスト") = list:[1, 2, '三']
methods:['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
list(0) = int:1
list(1) = int:2
list(2) = str:三
dict("タプル") = tuple:('山', '川', '谷')
methods:['count', 'index']
tuple(0) = str:山
tuple(1) = str:川
tuple(2) = str:谷
dict("辞書") = dict:{'キー1': '値1', 'キー2': '値2'}
methods:['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
dict("キー1") = str:値1
dict("キー2") = str:値2
dict("集合") = set:{frozenset({'二', '一'}), 1, 2}
methods:['add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
set(0) = frozenset:frozenset({'二', '一'})
methods:['copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']
frozenset(0) = str:二
frozenset(1) = str:一
set(1) = int:1
set(2) = int:2
dict("ブール値") = int:1
dict("None") = str:
dict("レンジ") = range:range(0, 2, 20)
range .start = int:0
range .step = int:20
range .stop = int:2
methods:['count', 'index']
range(0) = int:0
dict("バイトアレイ") = bytearray:bytearray(b'example bytearray')
methods:['append', 'capitalize', 'center', 'clear', 'copy', 'count', 'decode', 'endswith', 'expandtabs', 'extend', 'find', 'fromhex', 'hex', 'index', 'insert', 'isalnum', 'isalpha', 'isascii', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'pop', 'remove', 'removeprefix', 'removesuffix', 'replace', 'reverse', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
bytearray(0) = int:101
bytearray(1) = int:120
bytearray(2) = int:97
bytearray(3) = int:109
bytearray(4) = int:112
bytearray(5) = int:108
bytearray(6) = int:101
bytearray(7) = int:32
bytearray(8) = int:98
bytearray(9) = int:121
bytearray(10) = int:116
bytearray(11) = int:101
bytearray(12) = int:97
bytearray(13) = int:114
bytearray(14) = int:114
bytearray(15) = int:97
bytearray(16) = int:121
dict("バイト") = str:example bytes
dict("日時") = datetime:datetime.datetime(2024, 7, 20, 9, 47, 50, 200660)
datetime .day = int:20
datetime .fold = int:0
datetime .hour = int:9
datetime .max = datetime:datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
datetime .microsecond = int:200660
datetime .min = datetime:datetime.datetime(1, 1, 1, 0, 0)
datetime .minute = int:47
datetime .month = int:7
datetime .resolution = timedelta:datetime.timedelta(microseconds=1)
datetime .second = int:50
datetime .tzinfo = str:
datetime .year = int:2024
methods:['astimezone', 'combine', 'ctime', 'date', 'dst', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'now', 'replace', 'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday']
dict("日付") = date:datetime.date(2024, 7, 20)
date .day = int:20
date .max = date:datetime.date(9999, 12, 31)
date .min = date:datetime.date(1, 1, 1)
date .month = int:7
date .resolution = timedelta:datetime.timedelta(days=1)
date .year = int:2024
methods:['ctime', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'replace', 'strftime', 'timetuple', 'today', 'toordinal', 'weekday']
dict("混合") = list:[1, 2, 3, ['四', '五', {'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}]]
methods:['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
list(0) = int:1
list(1) = int:2
list(2) = int:3
list(3) = list:['四', '五', {'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}]
methods:['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
list(0) = str:四
list(1) = str:五
list(2) = dict:{'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}
methods:['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
dict("内部辞書1") = str:六
dict("タプル") = tuple:(8, 9, ('七', '八', {'さらに内部辞書': '九'}))
methods:['count', 'index']
tuple(0) = int:8
tuple(1) = int:9
tuple(2) = tuple:('七', '八', {'さらに内部辞書': '九'})
methods:['count', 'index']
tuple(0) = str:七
tuple(1) = str:八
tuple(2) = dict:{'さらに内部辞書': '九'}
methods:['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
dict("さらに内部辞書") = str:九
^||o="dict:{'整数': 42, '浮動小数点数': 3.14159, '文字列': 'こんにちは、世界!', 'リスト': [1, 2, '三'], 'タプル': ('山', '川', '谷'), '辞書': {'キー1': '値1', 'キー2': '値2'}, '集合': {frozenset({'二', '一'}), 1, 2}, 'ブール値': True, 'None': None, 'レンジ': range(0, 2, 20), 'バイトアレイ': bytearray(b'example bytearray'), 'バイト': b'example bytes', '日時': datetime.datetime(2024, 7, 20, 9, 47, 50, 200660), '日付': datetime.date(2024, 7, 20), '混合': [1, 2, 3, ['四', '五', {'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}]]}"
^||o("dict","None")="str:"
^||o("dict","methods")="['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']"
^||o("dict","タプル")="tuple:('山', '川', '谷')"
^||o("dict","タプル","tuple")=3
^||o("dict","タプル","tuple",0)="str:山"
^||o("dict","タプル","tuple",1)="str:川"
^||o("dict","タプル","tuple",2)="str:谷"
^||o("dict","タプル","tuple","methods")="['count', 'index']"
^||o("dict","バイト")="str:example bytes"
^||o("dict","バイトアレイ")="bytearray:bytearray(b'example bytearray')"
^||o("dict","バイトアレイ","bytearray")=17
^||o("dict","バイトアレイ","bytearray",0)="int:101"
^||o("dict","バイトアレイ","bytearray",1)="int:120"
^||o("dict","バイトアレイ","bytearray",2)="int:97"
^||o("dict","バイトアレイ","bytearray",3)="int:109"
^||o("dict","バイトアレイ","bytearray",4)="int:112"
^||o("dict","バイトアレイ","bytearray",5)="int:108"
^||o("dict","バイトアレイ","bytearray",6)="int:101"
^||o("dict","バイトアレイ","bytearray",7)="int:32"
^||o("dict","バイトアレイ","bytearray",8)="int:98"
^||o("dict","バイトアレイ","bytearray",9)="int:121"
^||o("dict","バイトアレイ","bytearray",10)="int:116"
^||o("dict","バイトアレイ","bytearray",11)="int:101"
^||o("dict","バイトアレイ","bytearray",12)="int:97"
^||o("dict","バイトアレイ","bytearray",13)="int:114"
^||o("dict","バイトアレイ","bytearray",14)="int:114"
^||o("dict","バイトアレイ","bytearray",15)="int:97"
^||o("dict","バイトアレイ","bytearray",16)="int:121"
^||o("dict","バイトアレイ","bytearray","methods")="['append', 'capitalize', 'center', 'clear', 'copy', 'count', 'decode', 'endswith', 'expandtabs', 'extend', 'find', 'fromhex', 'hex', 'index', 'insert', 'isalnum', 'isalpha', 'isascii', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'pop', 'remove', 'removeprefix', 'removesuffix', 'replace', 'reverse', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']"
^||o("dict","ブール値")="int:1"
^||o("dict","リスト")="list:[1, 2, '三']"
^||o("dict","リスト","list")=3
^||o("dict","リスト","list",0)="int:1"
^||o("dict","リスト","list",1)="int:2"
^||o("dict","リスト","list",2)="str:三"
^||o("dict","リスト","list","methods")="['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']"
^||o("dict","レンジ")="range:range(0, 2, 20)"
^||o("dict","レンジ","range")=1
^||o("dict","レンジ","range",0)="int:0"
^||o("dict","レンジ","range",".start")="int:0"
^||o("dict","レンジ","range",".step")="int:20"
^||o("dict","レンジ","range",".stop")="int:2"
^||o("dict","レンジ","range","methods")="['count', 'index']"
^||o("dict","整数")="int:42"
^||o("dict","文字列")="str:こんにちは、世界!"
^||o("dict","日付","date")="date:datetime.date(2024, 7, 20)"
^||o("dict","日付","date",".day")="int:20"
^||o("dict","日付","date",".max","date")="datetime.date(9999, 12, 31)"
^||o("dict","日付","date",".min","date")="datetime.date(1, 1, 1)"
^||o("dict","日付","date",".month")="int:7"
^||o("dict","日付","date",".resolution","timedelta")="datetime.timedelta(days=1)"
^||o("dict","日付","date",".year")="int:2024"
^||o("dict","日付","date","methods")="['ctime', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'replace', 'strftime', 'timetuple', 'today', 'toordinal', 'weekday']"
^||o("dict","日時","datetime")="datetime:datetime.datetime(2024, 7, 20, 9, 47, 50, 200660)"
^||o("dict","日時","datetime",".day")="int:20"
^||o("dict","日時","datetime",".fold")="int:0"
^||o("dict","日時","datetime",".hour")="int:9"
^||o("dict","日時","datetime",".max","datetime")="datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)"
^||o("dict","日時","datetime",".microsecond")="int:200660"
^||o("dict","日時","datetime",".min","datetime")="datetime.datetime(1, 1, 1, 0, 0)"
^||o("dict","日時","datetime",".minute")="int:47"
^||o("dict","日時","datetime",".month")="int:7"
^||o("dict","日時","datetime",".resolution","timedelta")="datetime.timedelta(microseconds=1)"
^||o("dict","日時","datetime",".second")="int:50"
^||o("dict","日時","datetime",".tzinfo")="str:"
^||o("dict","日時","datetime",".year")="int:2024"
^||o("dict","日時","datetime","methods")="['astimezone', 'combine', 'ctime', 'date', 'dst', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'now', 'replace', 'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday']"
^||o("dict","浮動小数点数")="float:3.141589999999999883"
^||o("dict","混合")="list:[1, 2, 3, ['四', '五', {'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}]]"
^||o("dict","混合","list")=4
^||o("dict","混合","list",0)="int:1"
^||o("dict","混合","list",1)="int:2"
^||o("dict","混合","list",2)="int:3"
^||o("dict","混合","list",3)="list:['四', '五', {'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}]"
^||o("dict","混合","list",3,"list")=3
^||o("dict","混合","list",3,"list",0)="str:四"
^||o("dict","混合","list",3,"list",1)="str:五"
^||o("dict","混合","list",3,"list",2)="dict:{'内部辞書1': '六', 'タプル': (8, 9, ('七', '八', {'さらに内部辞書': '九'}))}"
^||o("dict","混合","list",3,"list",2,"dict","methods")="['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']"
^||o("dict","混合","list",3,"list",2,"dict","タプル")="tuple:(8, 9, ('七', '八', {'さらに内部辞書': '九'}))"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple")=3
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",0)="int:8"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",1)="int:9"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2)="tuple:('七', '八', {'さらに内部辞書': '九'})"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2,"tuple")=3
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2,"tuple",0)="str:七"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2,"tuple",1)="str:八"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2,"tuple",2)="dict:{'さらに内部辞書': '九'}"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2,"tuple",2,"dict","methods")="['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2,"tuple",2,"dict","さらに内部辞書")="str:九"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple",2,"tuple","methods")="['count', 'index']"
^||o("dict","混合","list",3,"list",2,"dict","タプル","tuple","methods")="['count', 'index']"
^||o("dict","混合","list",3,"list",2,"dict","内部辞書1")="str:六"
^||o("dict","混合","list",3,"list","methods")="['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']"
^||o("dict","混合","list","methods")="['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']"
^||o("dict","辞書")="dict:{'キー1': '値1', 'キー2': '値2'}"
^||o("dict","辞書","dict","methods")="['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']"
^||o("dict","辞書","dict","キー1")="str:値1"
^||o("dict","辞書","dict","キー2")="str:値2"
^||o("dict","集合")="set:{frozenset({'二', '一'}), 1, 2}"
^||o("dict","集合","set")=3
^||o("dict","集合","set",0)="frozenset:frozenset({'二', '一'})"
^||o("dict","集合","set",0,"frozenset")=2
^||o("dict","集合","set",0,"frozenset",0)="str:二"
^||o("dict","集合","set",0,"frozenset",1)="str:一"
^||o("dict","集合","set",0,"frozenset","methods")="['copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']"
^||o("dict","集合","set",1)="int:1"
^||o("dict","集合","set",2)="int:2"
^||o("dict","集合","set","methods")="['add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']"
USER>
USER>d s^Py.Dump(10)
こんにちは、私の名前は 山田 で、30 歳です。
こんにちは、私の名前は 上田 で、25 歳です。
tuple:(<Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78D128490>, <Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78DCF0580>)
methods:['count', 'index']
tuple(0) = Person:<Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78D128490>
Person .age = int:30
Person .name = str:山田
methods:['greet']
tuple(1) = Person:<Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78DCF0580>
Person .age = int:25
Person .name = str:上田
methods:['greet']
^||o="tuple:(<Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78D128490>, <Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78DCF0580>)"
^||o("tuple")=2
^||o("tuple",0,"Person")="Person:<Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78D128490>"
^||o("tuple",0,"Person",".age")="int:30"
^||o("tuple",0,"Person",".name")="str:山田"
^||o("tuple",0,"Person","methods")="['greet']"
^||o("tuple",1,"Person")="Person:<Py.Sample.Sample.s10.<locals>.Person object at 0x000001C78DCF0580>"
^||o("tuple",1,"Person",".age")="int:25"
^||o("tuple",1,"Person",".name")="str:上田"
^||o("tuple",1,"Person","methods")="['greet']"
^||o("tuple","methods")="['count', 'index']"
USER>