LibreOffice(51)クラスにすると関数の引数が減らせた

ラベル: ,

前の関連記事:LibreOffice(50)オブジェクトから継承図をたどってメソッド一覧を得る


関数が複数になってきて引数が増えてきたので全部一つのクラスにいれたらself.で共通に使える変数にできるので引数が減ってとてもわかりやすくなりました。

その後で使うのでなければfor文の中でできることはfor文の中ですることに変更


            lst_std = list(map(tdm.getByHierarchicalName, t_ss))  # t_ssの要素のサービス名からXServiceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
            for std in lst_std:  # 各サービスについて親のサービスを得る。
                t_std = std.getMandatoryServices()+std.getOptionalServices()  # 直に継承しているサービスのXServiceTypeDescription2インターフェイスをもつオブジェクトのタプルを取得。
例えばこれはfor文の前にlst_stdを生成しなくてもfor文の中でやってしまえばよいことに気づきました。
           for ss in t_ss:  # 各サービス名について親のサービスを得る。
                std = tdm.getByHierarchicalName(ss)  # サービス名からXServiceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                t_std = std.getMandatoryServices()+std.getOptionalServices()  # 直に継承しているサービスのXServiceTypeDescription2インターフェイスをもつオブジェクトのタプルを取得。
これでも同じことです。

これはmapを使ってリストを生成しなおしていますが、他にもリストの内包表記でリストを生成しなおしてからfor文を回しているところがあります。

いいことに気がついたと思ってLibreOffice(50)オブジェクトから継承図をたどってメソッド一覧を得るをあちこち直そうと思ったら生成しなおしたリストを使っている部分が多くて結局修正したのはこの部分だけでした。

しかもこの部分もfor文のあとのsa_dic_g()でlst_stdを使っていたので結局修正しないほうがよいと思いました。

きっと最初にコードを書いたときに意識せずに考えていたのだと思います、、、

一応上記の部分を修正したときの場合のコードを載せておきます。

14行目と64行目の部分が同じことをしていることになるので効率は却って落ちると思われます。
def libreoffice51():
    obj = XSCRIPTCONTEXT.getDocument()  # 調査対象のオブジェクトを取得。old-styleサービスの例。LibreOfficeドキュメントを開いておく必要がある。
    # obj = XSCRIPTCONTEXT.getDesktop().getCurrentFrame().getContainerWindow().getToolkit() # 調査対象のオブジェクトを取得。new-styleサービスの例。
    # obj = XSCRIPTCONTEXT.getComponentContext()  # 調査対象のオブジェクトを取得。サービスがないオブジェクトの例。
    s_omi = {'com.sun.star.uno.XInterface', 'com.sun.star.uno.XWeak', 'com.sun.star.lang.XTypeProvider'}  # 結果を出力しないインターフェイス名の集合。'com.sun.star.uno.XInterface'は必ず指定が必要。
    tdm = XSCRIPTCONTEXT.getComponentContext().getByName('/singletons/com.sun.star.reflection.theTypeDescriptionManager')  # TypeDescriptionManagerをシングルトンでインスタンス化。
    s_dic = dict()  # key:子サービス名、value:親サービスのタプル。
    i_dic = dict()  # key:子インターフェイス名または子サービス名、value:親インターフェイスのタプル。
    lst_itd = list()
    if hasattr(obj, "getSupportedServiceNames"):  # hasattr()は属性の有無をチェックするPythonの組み込み関数。
        t_ss = obj.getSupportedServiceNames()  # サポートしているサービス名のタプルを取得。
        if t_ss:  # サポートしているサービスがある場合。
            for ss in t_ss:  # 各サービス名について親のサービスを得る。
                std = tdm.getByHierarchicalName(ss)  # サービス名からXServiceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                t_std = std.getMandatoryServices()+std.getOptionalServices()  # 直に継承しているサービスのXServiceTypeDescription2インターフェイスをもつオブジェクトのタプルを取得。
                if t_std:  # 直に継承しているサービスがあるのなら
                    s_dic[std.Name] = t_std  # 直に継承しているサービスのTypeDescriptionオブジェクトのタプルを子のサービス名をkeyにしてdicに取得。
                if std.isSingleInterfaceBased():  # new-style(single-interface–based)サービスのとき
                    lst_itd = [std.getInterface()]  # サービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトでリストにして取得。
                else:  # old-style(accumulation-based)サービスのとき
                    lst_itd = [i for i in std.getMandatoryInterfaces() + std.getOptionalInterfaces() if i.Name not in s_omi]  # o_omiを除いてサービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                    # print([j.Name for i in s_dic.values() for j in i])  # 2次元になっている辞書のvalueを1次元に展開し、各要素についてName属性のリストを出力。
                    # print("\n".join([str(k) for k in zip(s_dic.keys(), [[j.Name for j in i]for i in s_dic.values()])]))  # s_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
                if lst_itd:  # 親インターフェイスが存在するとき。
                    i_dic[std.Name] = lst_itd  # サービス名を子、インターフェイスのタプルを親にしてdicに取得。
                    get_interfaces2(lst_itd, i_dic, s_omi)  # 親インターフェイスをたどってi_dicの項目を追加する。
            s_ss = set(t_ss)  # サービス名のリストを集合型に変換。
            lst_des = s_ss.intersection(s_ss ^ set([j.Name for i in s_dic.values() for j in i]))  # オブジェクトから得たサービスのうち、辞書dicのvalueにない(親になっていない)サービス名(=末裔)をリストで取得。
            sa_dic = sa_dic_g(t_ss, tdm)  # サポートするサービスのリストを元に辞書sa_dicを生成。key:サービス名、value:サービスの属性のXTypeDescriptionオブジェクトのタプル。
            lst_itd = [j for i in i_dic.values() for j in i]  # 辞書i_dicのvalueのインターフェイスのタプルを展開して取得。
            # print("\n".join([str(k) for k in zip(sa_dic.keys(), [[j.Name for j in i] for i in sa_dic.values()])]))  # 辞書sa_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
            # print("\n".join([str(k) for k in zip(sa_dic.keys(), [[j.PropertyTypeDescription.Name for j in i] for i in sa_dic.values()])]))  # 辞書sa_dicの2次元のvalueを展開してPropertyTypeDescription.Name属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
    else:  # サポートしているサービスがないときはインターフェイス名一覧を得る。
        if hasattr(obj, "getTypes"):
            lst_si = obj.getTypes()  # インターフェイス名のリストを取得。<Type instance インターフェイス名 (<uno.Enum com.sun.star.uno.TypeClass ('INTERFACE')>)>、といったものが返ってきますが型不明。
            if lst_si:  # サポートしているインターフェイスがあるとき。
                s_si = set([i.typeName for i in obj.getTypes()])  # インターフェイス名一覧を集合型に変換。
                lst_des = s_si.intersection(s_si ^ s_omi)  # s_omiのインターフェイス名を除いてインターフェイス名(=末裔)をリストで取得。
                if lst_des:  # 残ったインターフェイスのリストがあるとき
                    lst_itd = list(map(tdm.getByHierarchicalName, lst_des))  # lst_siの要素のインターフェイス名からXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                    get_interfaces2(lst_itd, i_dic, s_omi)  # 親インターフェイスをたどってi_dicの項目を追加する。
                    lst_itd = lst_itd + [j for i in i_dic.values() for j in i]  #  サポートするインターフェイスのリストと辞書i_dicのvalueのインターフェイスのタプルを展開したリストを結合。
    if lst_itd:  # オブジェクトの全てのインターフェイスのリストがあるとき。
        im_dic = im_dic_g(lst_itd)  # 辞書im_dicを生成。key:インターフェイス名、value:インターフェイスのメソッドのXTypeDescriptionオブジェクトのタプル。
    # print("\n".join([str(k) for k in zip(i_dic.keys(), [[j.Name for j in i] for i in i_dic.values() ])]))  # i_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
    # print([i for i in lst_des])  # 末裔のリストを出力。
    # print("\n".join([str(k) for k in zip(im_dic.keys(), [[j.MemberName for j in i] for i in im_dic.values()])]))  # 辞書im_dicの2次元のvalueを展開してMemberName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
def get_interfaces2(t_itd, i_dic, s_omi):  # 親インターフェイスをs_omiにあるインターフェイスの手前まで取得する。
    u = get_interfaces(t_itd, i_dic, s_omi)  # インターフェイスのリストからさらに親のインターフェイスのタプルをdicに得る。戻り値は追加されたインターフェイスのタプルのリスト。
    while u:  # dicに新たに追加された値がある間は実行。
        for t_itd in u:  # 新たに追加されたTypeDescriptionオブジェクトのタプルについて。
            u = get_interfaces(t_itd, i_dic, s_omi) # インターフェイスのタプルからさらに親のインターフェイスのタプルをdicに得る。
def get_interfaces(t_itd, i_dic, s_omi):  # 辞書i_dicにkey:子インターフェイス名、value:親インターフェイスのリストを追加。
    v = list()  # 新たに追加になったdicのvalue(インターフェイスのタプル)を入れるリスト。
    for itd in t_itd:  # 各インターフェイスについて親のインターフェイスを得る。
        lst_itd = [i for i in itd.getBaseTypes()+itd.getOptionalBaseTypes() if i.Name not in s_omi]  # o_omiを除くインターフェイスのリストを取得。
        if lst_itd:  # 親インターフェイスのリストがあるとき
            i_dic[itd.Name] = lst_itd # インターフェイス名を子にして親のインターフェイスのタプルをdicに取得。
            v.append(i_dic[itd.Name])  # dicに新たに追加したインターフェイスのタプルをリストuに追加。
    return v  # vを戻り値で返す。
def sa_dic_g(t_ss, tdm):  # XServiceTypeDescription2インターフェイスをもつオブジェクトのリストから辞書sa_dicを生成。
    sa_dic = dict()  # 辞書sa_dic、key:サービス名、value:サービスの属性のXTypeDescriptionオブジェクトのタプル。
    for ss in t_ss:  # 各サービスについて。
        std = tdm.getByHierarchicalName(ss)
        t_sp = std.Properties  # XPropertyTypeDescriptionインターフェイスをもつオブジェクトのタプルを取得。
        if t_sp:
            sa_dic[std.Name] = t_sp  # 辞書sa_dicの項目を追加。
    return sa_dic  # 生成した辞書sa_dicを返す。
def im_dic_g(lst_itd):  # XInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストから辞書im_dicを生成。
    im_dic = dict()  # 辞書im_dic、key:インターフェイス名、value:インターフェイスのメソッドのXTypeDescriptionオブジェクトのタプル。
    for itd in lst_itd:  # 各インターフェイスについて
        t_im = itd.Members  # XInterfaceMemberTypeDescription型のオブジェクトのタプルを取得。メンバーがメソッドならXInterfaceMethodTypeDescriptionインターフェイスをもつ、属性ならXInterfaceAttributeTypeDescription2 インターフェイスをもつ。
        if t_im:
            im_dic[itd.Name] = t_im  # 辞書im_dicの項目を追加。 
    return im_dic  # 生成した辞書im_dicを返す。
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    libreoffice51()
lst_desがTypeDescriptionのリストからそのNameのリストに変更になっています。

13行目と63行目、55行目と71行目は同じfor文になっているでくっつけられそうです。

同じものをループさせているfor文を統合する


def libreoffice51():
    obj = XSCRIPTCONTEXT.getDocument()  # 調査対象のオブジェクトを取得。old-styleサービスの例。LibreOfficeドキュメントを開いておく必要がある。
    # obj = XSCRIPTCONTEXT.getDesktop().getCurrentFrame().getContainerWindow().getToolkit() # 調査対象のオブジェクトを取得。new-styleサービスの例。
    # obj = XSCRIPTCONTEXT.getComponentContext()  # 調査対象のオブジェクトを取得。サービスがないオブジェクトの例。
    s_omi = {'com.sun.star.uno.XInterface', 'com.sun.star.uno.XWeak', 'com.sun.star.lang.XTypeProvider'}  # 結果を出力しないインターフェイス名の集合。'com.sun.star.uno.XInterface'は必ず指定が必要。
    tdm = XSCRIPTCONTEXT.getComponentContext().getByName('/singletons/com.sun.star.reflection.theTypeDescriptionManager')  # TypeDescriptionManagerをシングルトンでインスタンス化。
    s_dic = dict()  # key:子サービス名、value:親サービスのタプル。
    i_dic = dict()  # key:子インターフェイス名または子サービス名、value:親インターフェイスのタプル。
    im_dic = dict()  # 辞書im_dic、key:インターフェイス名、value:インターフェイスのメソッドのXTypeDescriptionオブジェクトのタプル。
    if hasattr(obj, "getSupportedServiceNames"):  # hasattr()は属性の有無をチェックするPythonの組み込み関数。
        t_ss = obj.getSupportedServiceNames()  # サポートしているサービス名のタプルを取得。
        if t_ss:  # サポートしているサービスがある場合。
            sa_dic = dict()  # 辞書sa_dic、key:サービス名、value:サービスの属性のXTypeDescriptionオブジェクトのタプル。
            for ss in t_ss:  # 各サービス名について親のサービスを得る。
                std = tdm.getByHierarchicalName(ss)  # サービス名からXServiceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                t_std = std.getMandatoryServices()+std.getOptionalServices()  # 直に継承しているサービスのXServiceTypeDescription2インターフェイスをもつオブジェクトのタプルを取得。
                if t_std: s_dic[std.Name] = t_std  # 直に継承しているサービスのTypeDescriptionオブジェクトのタプルを子のサービス名をkeyにしてdicに取得。
                if std.isSingleInterfaceBased():  # new-style(single-interface–based)サービスのとき
                    lst_itd = [std.getInterface()]  # サービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトでリストにして取得。
                else:  # old-style(accumulation-based)サービスのとき
                    lst_itd = [i for i in std.getMandatoryInterfaces() + std.getOptionalInterfaces() if i.Name not in s_omi]  # o_omiを除いてサービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                    # print([j.Name for i in s_dic.values() for j in i])  # 2次元になっている辞書のvalueを1次元に展開し、各要素についてName属性のリストを出力。
                    # print("\n".join([str(k) for k in zip(s_dic.keys(), [[j.Name for j in i]for i in s_dic.values()])]))  # s_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
                if lst_itd:  # 親インターフェイスが存在するとき。
                    i_dic[std.Name] = lst_itd  # サービス名を子、インターフェイスのタプルを親にしてdicに取得。
                    get_interfaces2(lst_itd, i_dic, s_omi, im_dic)  # 親インターフェイスをたどってi_dicの項目を追加する。
                t_sp = std.Properties  # サービスからXPropertyTypeDescriptionインターフェイスをもつオブジェクトのタプルを取得。
                if t_sp: sa_dic[std.Name] = t_sp  # 辞書sa_dicの項目を追加。
            s_ss = set(t_ss)  # サービス名のリストを集合型に変換。
            lst_des = s_ss.intersection(s_ss ^ set([j.Name for i in s_dic.values() for j in i]))  # オブジェクトから得たサービスのうち、辞書dicのvalueにない(親になっていない)サービス名(=末裔)をリストで取得。
            # print("\n".join([str(k) for k in zip(sa_dic.keys(), [[j.Name for j in i] for i in sa_dic.values()])]))  # 辞書sa_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
            # print("\n".join([str(k) for k in zip(sa_dic.keys(), [[j.PropertyTypeDescription.Name for j in i] for i in sa_dic.values()])]))  # 辞書sa_dicの2次元のvalueを展開してPropertyTypeDescription.Name属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
    else:  # サポートしているサービスがないときはインターフェイス名一覧を得る。
        if hasattr(obj, "getTypes"):
            lst_si = obj.getTypes()
            if lst_si:  # サポートしているインターフェイスがあるとき。
                s_si = set([i.typeName for i in obj.getTypes()])  # インターフェイス名一覧を集合型に変換。
                lst_des = s_si.intersection(s_si ^ s_omi)  # s_omiのインターフェイス名を除いてインターフェイス名(=末裔)をリストで取得。
                if lst_des:  # 残ったインターフェイスのリストがあるとき
                    lst_itd = list(map(tdm.getByHierarchicalName, lst_des))  # lst_siの要素のインターフェイス名からXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                    get_interfaces2(lst_itd, i_dic, s_omi, im_dic)  # 親インターフェイスをたどってi_dicの項目を追加する。
    # print("\n".join([str(k) for k in zip(i_dic.keys(), [[j.Name for j in i] for i in i_dic.values() ])]))  # i_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
    # print([i for i in lst_des])  # 末裔のリストを出力。
    # print("\n".join([str(k) for k in zip(im_dic.keys(), [[j.MemberName for j in i] for i in im_dic.values()])]))  # 辞書im_dicの2次元のvalueを展開してMemberName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
def get_interfaces2(t_itd, i_dic, s_omi, im_dic):  # 親インターフェイスをs_omiにあるインターフェイスの手前まで取得する。
    u = get_interfaces(t_itd, i_dic, s_omi, im_dic)  # インターフェイスのリストからさらに親のインターフェイスのタプルをdicに得る。戻り値は追加されたインターフェイスのタプルのリスト。
    while u:  # dicに新たに追加された値がある間は実行。
        for t_itd in u:  # 新たに追加されたTypeDescriptionオブジェクトのタプルについて。
            u = get_interfaces(t_itd, i_dic, s_omi, im_dic) # インターフェイスのタプルからさらに親のインターフェイスのタプルをdicに得る。
def get_interfaces(t_itd, i_dic, s_omi, im_dic):  # 辞書i_dicにkey:子インターフェイス名、value:親インターフェイスのリストを追加。
    v = list()  # 新たに追加になったdicのvalue(インターフェイスのタプル)を入れるリスト。
    for itd in t_itd:  # 各インターフェイスについて親のインターフェイスを得る。
        t_im = itd.Members  # XInterfaceMemberTypeDescription型のオブジェクトのタプルを取得。メンバーがメソッドならXInterfaceMethodTypeDescriptionインターフェイスをもつ、属性ならXInterfaceAttributeTypeDescription2 インターフェイスをもつ。
        if t_im: im_dic[itd.Name] = t_im  # 辞書im_dicの項目を追加。 
        lst_itd = [i for i in itd.getBaseTypes()+itd.getOptionalBaseTypes() if i.Name not in s_omi]  # o_omiを除く親インターフェイスのリストを取得。
        if lst_itd:  # 親インターフェイスのリストがあるとき
            i_dic[itd.Name] = lst_itd # インターフェイス名を子にして親のインターフェイスのタプルをdicに取得。
            v.append(i_dic[itd.Name])  # dicに新たに追加したインターフェイスのタプルをリストuに追加。
    return v  # vを戻り値で返す。
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    libreoffice51()
重複したfor文をまとめました。

関数から呼び出している関数をクラスにいれて引数を減らす


関数の引数がどんどん増えてくるのでクラスにして引数をクラスのローカル変数にしてしまいます。

生成する辞書と複数の関数で使う共通の引数を全部クラスの変数にしてしまいます。
def libreoffice51():
    obj = XSCRIPTCONTEXT.getDocument()  # 調査対象のオブジェクトを取得。old-styleサービスの例。LibreOfficeドキュメントを開いておく必要がある。
    # obj = XSCRIPTCONTEXT.getDesktop().getCurrentFrame().getContainerWindow().getToolkit() # 調査対象のオブジェクトを取得。new-styleサービスの例。
    # obj = XSCRIPTCONTEXT.getComponentContext()  # 調査対象のオブジェクトを取得。サービスがないオブジェクトの例。
    ObjInsp(obj)
class ObjInsp:
    def __init__(self, obj):
        self.s_dic = dict()  # サービス辞書。key:子サービス名、value:親サービスのタプル。以下辞書のvalueは全てXTypeDescriptionオブジェクトのタプル。
        self.sa_dic = dict()  # サービス属性辞書。key:サービス名、value:サービスの属性のタプル。
        self.i_dic = dict()  # インターフェイス辞書。key:子インターフェイス名または子サービス名、value:親インターフェイスのタプル。
        self.im_dic = dict()  # メソッド辞書。key:インターフェイス名、value:インターフェイスのメソッドのタプル。
        self.s_omi = {'com.sun.star.uno.XInterface', 'com.sun.star.uno.XWeak', 'com.sun.star.lang.XTypeProvider'}  # 結果を出力しないインターフェイス名の集合。'com.sun.star.uno.XInterface'は必ず指定が必要。
        tdm = XSCRIPTCONTEXT.getComponentContext().getByName('/singletons/com.sun.star.reflection.theTypeDescriptionManager')  # TypeDescriptionManagerをシングルトンでインスタンス化。
        if hasattr(obj, "getSupportedServiceNames"):  # hasattr()は属性の有無をチェックするPythonの組み込み関数。
            t_ss = obj.getSupportedServiceNames()  # サポートしているサービス名のタプルを取得。
            if t_ss:  # サポートしているサービス名がある場合。
                for ss in t_ss:  # 各サービス名について親のサービスを得る。
                    std = tdm.getByHierarchicalName(ss)  # サービス名からXServiceTypeDescription2インターフェイスをもつオブジェクトを取得。
                    self.sa_dic_g(std)  # サービス属性辞書追加関数。
                    self.i_dic_g2(std)  # サービスからインターフェイス辞書追加関数。
                    t_std = std.getMandatoryServices()+std.getOptionalServices()  # 直に継承しているサービス(親サービス)のタプルを得る。
                    if t_std: self.s_dic[std.Name] = t_std  # 親サービスがあるときサービス辞書に追加。
                    lst_buf = t_std  # バッファリストに親サービスのタプルを代入。有無をみるだけなのでリストに変換しない。
                    while lst_buf:  # バッファリストがある間継続。
                        lst_buf = list()  # バッファリストを初期化。
                        for std in t_std:  # 各親サービスについて。
                            self.sa_dic_g(std)  # サービス属性辞書追加関数。
                            self.i_dic_g2(std)  # サービスからインターフェイス辞書追加関数。
                            t_std = std.getMandatoryServices()+std.getOptionalServices()  # さらなる親サービスを取得。
                            if t_std:  # 親サービスがあるなら。
                                self.s_dic[std.Name] = t_std  # サービス辞書に追加。
                                lst_buf.extend(t_std)  # バッファリストに親サービスのタプルを追加。
                        t_std = lst_buf  # バッファリストから次の階層のサービスのリストを得る。
                self.lst_des(t_ss)  # サービス名からサービスの末裔を得る関数。
                # print("\n".join([str(k) for k in zip(self.s_dic.keys(), [[j.Name for j in i]for i in self.s_dic.values()])]))  # s_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
                # print("\n".join([str(k) for k in zip(self.sa_dic.keys(), [[j.Name for j in i] for i in self.sa_dic.values()])]))  # 辞書sa_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
                # print("\n".join([str(k) for k in zip(sa_dic.keys(), [[j.PropertyTypeDescription.Name for j in i] for i in sa_dic.values()])]))  # 辞書sa_dicの2次元のvalueを展開してPropertyTypeDescription.Name属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
        else:  # サポートしているサービスがないときはインターフェイス名一覧を得る。
            if hasattr(obj, "getTypes"):
                lst_si = obj.getTypes()
                if lst_si:  # サポートしているインターフェイスがあるとき。
                    s_si = set([i.typeName for i in obj.getTypes()])  # インターフェイス名一覧を集合型に変換。
                    self.lst_des = s_si.intersection(s_si ^ self.s_omi)  # s_omiのインターフェイス名を除いてインターフェイス名(=末裔)をリストで取得。
                    if self.lst_des:  # 残ったインターフェイスのリストがあるとき
                        lst_itd = list(map(tdm.getByHierarchicalName, self.lst_des))  # lst_siの要素のインターフェイス名からXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
                        self.i_dic_g(lst_itd)
        # print("\n".join([str(k) for k in zip(self.i_dic.keys(), [[j.Name for j in i] for i in self.i_dic.values() ])]))  # i_dicの2次元のvalueを展開してName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
        # print([i for i in self.lst_des])  # 末裔のリストを出力。
        # print("\n".join([str(k) for k in zip(self.im_dic.keys(), [[j.MemberName for j in i] for i in self.im_dic.values()])]))  # 辞書im_dicの2次元のvalueを展開してMemberName属性のリストを取得して、keyのリストと組み合わせたリストを生成して各要素を改行文字で結合して出力。
    def sa_dic_g(self, std):  # サービス辞書追加関数。
        t_sp = std.Properties  # サービスからXPropertyTypeDescriptionインターフェイスをもつオブジェクトのタプルを取得。
        if t_sp: self.sa_dic[std.Name] = t_sp  # サービス属性辞書に追加。
    def im_dic_g(self, itd):  # メソッド辞書追加関数。
            t_im = itd.Members  # XInterfaceMemberTypeDescription型のオブジェクトのタプルを取得。メンバーがメソッドならXInterfaceMethodTypeDescriptionインターフェイスをもつ、属性ならXInterfaceAttributeTypeDescription2 インターフェイスをもつ。
            if t_im: self.im_dic[itd.Name] = t_im  # メソッドがあるならメソッド辞書に追加。 
    def lst_des(self, t_ss):  # サービス名からサービスの末裔を得る関数。
        if self.s_dic:  # サービス辞書に項目があるとき。
            s_ss = set(t_ss)  # サービス名のリストを集合型に変換。
            self.lst_des = s_ss.intersection(s_ss ^ set([j.Name for i in self.s_dic.values() for j in i]))  # オブジェクトから得たサービスのうち、サービス辞書のvalueにない(親になっていない)サービス名(=末裔)をリストで取得。
        else:  # サービス辞書に項目がないとき
            self.lst_des = t_ss  # サポートしているサービス名を末裔とする。
    def i_dic_g2(self, std):  # サービスからインターフェイス辞書追加関数。
        if std.isSingleInterfaceBased():  # new-style(single-interface–based)サービスのとき
            lst_itd = [std.getInterface()]  # サービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトでリストにして取得。
        else:  # old-style(accumulation-based)サービスのとき
            lst_itd = [i for i in std.getMandatoryInterfaces() + std.getOptionalInterfaces() if i.Name not in self.s_omi]  # o_omiを除いてサービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。
        if lst_itd: self.i_dic[std.Name] = lst_itd  # サービス名をkeyにしてその親インターフェイスのリストを得る。
        self.i_dic_g(lst_itd)  # インターフェイス辞書追加関数。
    def i_dic_g(self, lst_itd):  # インターフェイス辞書追加関数。
        lst_buf = lst_itd  # バッファリストに親インターフェイスのタプルを代入。有無をみるだけなのでリストに変換しない。
        while lst_buf:  # バッファリストがある間継続。
            lst_buf = list()  # バッファリストを初期化。
            for itd in lst_itd:  # 各親インターフェイスについて。
                self.im_dic_g(itd)  # メソッド辞書追加関数。
                lst_itd = [i for i in itd.getBaseTypes()+itd.getOptionalBaseTypes() if i.Name not in self.s_omi]  # さらなる親インターフェイスのリストをo_omiを除いて取得。
                if lst_itd:  # 親インターフェイスがあるなら。
                    self.i_dic[itd.Name] = lst_itd  # インターフェイス辞書に追加。
                    lst_buf.extend(lst_itd)  # バッファリストに親インターフェイスのリストを追加。
            lst_itd = lst_buf  # バッファリストから次の階層のインターフェイスのリストを得る。
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    libreoffice51()
サービスの階層を1段階しか取得していなかったので全部取得するようにしました。

さあこれで全ての辞書がそろったはずです。

これは多分木でやったほうがよさそうなことに気づく


ちょっといろいろしてみましたが思ったように出力できませんねぇ。

libreoffice51.py

いちおうこれで辞書の一覧を出力できましたが取得したときのように1階層ずつそろって出すようになっています。

一つずつ階層を底までいってからまた返ってくるというふうにしたいのですがwhileを使ってあれこれしてもうまいやりかたがわかりません。

[ThinkIT] 第5回:教科書的ではなく、現場にあったデータベース設計のコツ (1/3)

階層データの取扱方法について調べていたらこの解説を見つけました。

いまやっているのは「親番号方式」になると思います。

「パス方式」はエクスプローラでのファイル管理と同じような方法です。

この方法は一番最初に思いついたのですが辞書のkeyにパスを入れると思っていたのでkeyを更新していくのはややこしそうだなと思ってやめたのですが、よく考えたら階層ごとに出てくるほうをkeyにして辞書を作り直して、パスはvalueにいれていけばいけそうだと気づきました。

pyunoオブジェクトをkeyにすることはできないのでName属性だけとりだしてkeyにして最後にメソッド名をkey、その由来のサービスとインターフェイスの階層のパスをvalueとする辞書が完成してから、 keyとvalueをひっくり返してメソッド名をXTypeDescriptionオブジェクトに変換しなおせばよいはずです。

また一から全部作り直しです。

そう思って作り直しを始めたらPythonの二分木の解説を見つけました。

Algorithms with Python / 二分木, ヒープ

巡回 (traverse)のところを読むとこの方式で階層を底までいってからまた元に戻って次の底まで行くということができそうに思えました。

これを二分木でなくて多分木でやらないといけませんけど。

参考にしたサイト


GitHubについてもう少し知ってみる。その5(Gistでお手軽コード管理) | Alpac@labo
ブログにそのまま載せるにはコードが長くなりすぎたのでGistを使うことにしました。

[ThinkIT] 第5回:教科書的ではなく、現場にあったデータベース設計のコツ (1/3)
階層構造データを扱う二つの方式。「親番号方式」と「パス方式」。

Algorithms with Python / 二分木, ヒープ
Pythonで二分木を扱う方法の解説があります。

ソート HOW TO — Python 3.3.3 ドキュメント
Key 関数を使うと要素の属性などでソートできます。

次の関連記事:LibreOffice(52)サービス辞書とインターフェイス辞書の結果を図に書く

PR

0 件のコメント:

コメントを投稿