编程语言
首页 > 编程语言> > vscode 使用 python 进行 UG 二次开发 实现代码提示功能

vscode 使用 python 进行 UG 二次开发 实现代码提示功能

作者:互联网

vscode 使用 python 进行 UG 二次开发的 实现代码提示功能

用 VSCODE 进行 UG 二次开发的时候, 想要用代码提示的时候,可以用 pydev 插件, 但是,pydev 只有一个月的试用期,那到用 pylance 可不可以有相似的效果吗?

答案是可以。

方法是 自己生成 NXOpen.pyi 文件。


自已写了一段代码,用于简单的生成 这个 文件。


from typing import Dict, Generator, List, Optional
import NXOpen
import types
import os
from importlib import import_module

ugii_base_dir = os.getenv("UGII_BASE_DIR")

pp = os.path.join(str(ugii_base_dir), "nxbin", "python")

imp_mds = {}
for root, dirs, files in os.walk(pp, topdown=True):

    if root != pp:
        break

    for ff in files:
        # print(ff)
        if str(ff).startswith("NXOpen_") and str(ff).endswith(".pyd"):
            module_name = str(ff)[:-4]
            # print(module_name)
            try:
                ms = module_name.split("_")[-1]
                imp_mds[ms] = import_module(module_name)
            except Exception as e:
                print("error:", module_name, e)


class pyibase:

    # ecpts = ["TaggedObject", "INXObject"]
    ecpts = [
        "NXObject",
        "TaggedObject",
        "INXObject",
    ]

    def __init__(self) -> None:
        self.name: str = ""
        self.doc: Optional[str] = ""
        self.chdmdls: Dict = {}
        self.chdtps: Dict = {}
        self.MdDescriptor: Dict = {}
        self.GSDescriptor: Dict = {}
        self.unct: Dict = {}
        self.nxc: Dict[str, "nxcs | pyibase"] = {}
        self.mthdorbutin: Dict = {}
        self.mberDescriptor: Dict = {}
        self.nn: List[str] = []

    def dcts(self) -> Generator["pyibase", None, None]:
        for dc in [
            self.chdmdls,
            self.chdtps,
            self.MdDescriptor,
            self.GSDescriptor,
            self.unct,
            self.nxc,
            self.mthdorbutin,
            self.mberDescriptor,
        ]:
            for v in dc.values():
                yield v

    def addmember(self, m, dm: List[str] = None):

        dirm = dir(m)
        # if dm is not None:
        #     dirm = [i for i in dirm if i not in dm]
        for i in dirm:
            if i == "GetSession":
                print(i)
            if not i.startswith("_"):
                att = getattr(m, i)
                self.nn.append(i)
                if isinstance(att, types.ModuleType):
                    self.chdmdls[i] = mdls(att)
                elif isinstance(att, type):
                    if i not in pyibase.ecpts:
                        self.chdtps[i] = tps(att)
                elif isinstance(att, types.MethodDescriptorType):
                    self.MdDescriptor[i] = mdDscp(att)
                elif isinstance(att, types.GetSetDescriptorType):
                    self.GSDescriptor[i] = gsDscp(att)
                elif isinstance(att, types.MemberDescriptorType):
                    self.mberDescriptor[i] = mmDscp(att)
                else:
                    _md = att.__class__.__module__
                    if "NXOpen" in str(_md):
                        self.nxc[i] = nxcs(att, i)
                    elif i == "ValueOf":
                        self.mthdorbutin[i] = bmDscp(att)
                    elif isinstance(att, types.BuiltinFunctionType):
                        self.mthdorbutin[i] = bmDscp(att)
                    else:
                        assert TypeError(i, att, type(att))

    def docs(self, lv: int = 0, mx: int = 130):
        dd = str(self.doc)
        dd = dd.strip()
        dd2 = dd.splitlines()
        dd2 = [i.strip() for i in dd2]

        ll = mx - lv * 4
        yield (lv + 1) * "\t" + "'''"
        for i in dd2:
            for k in range(0, len(i), ll):
                yield (lv + 1) * "\t" + i[k : min(len(i), k + ll)]
        yield (lv + 1) * "\t" + "'''"

    def toStr(self, lv: int = 0, mx: int = 130):
        yield lv * "\t" + f"{self.name}:-->"


class mdls(pyibase):
    def __init__(self, m: types.ModuleType) -> None:
        super().__init__()
        assert isinstance(m, types.ModuleType)
        self.doc = m.__doc__
        self.name = m.__name__.split(".")[-1]

        self.addmember(m)

    def toStr(self, lv: int = 0, mx: int = 130):
        yield f"class {self.name}:"
        for dc in self.dcts():
            for i in dc.toStr(1):
                yield i


class basetps(pyibase):
    def __init__(self, m: type, name="") -> None:
        super().__init__()
        assert name in pyibase.ecpts
        self.name = name
        self.doc = m.__doc__
        self.mo = type.mro(m)
        self.addmember(m)

    def toStr(self, lv=0, mx=130):
        if self.name in ["TaggedObject", "INXObject"]:
            yield lv * "\t" + f"class {self.name}(object):"
        elif self.name == "NXObject":
            yield lv * "\t" + f"class {self.name}(TaggedObject,INXObject):"
        else:
            yield lv * "\t" + f"class {self.name}(object):"
        for i in self.docs(lv):
            yield i
        for v in self.dcts():
            for ss in v.toStr(lv + 1):
                yield ss


class tps(pyibase):
    def __init__(self, m: type) -> None:
        super().__init__()
        assert isinstance(m, type)
        self.doc = m.__doc__
        self.name = m.__name__
        self.mo = type.mro(m)
        self.sp = self.mo[1]
        ll = []
        for k in self.mo[1:]:
            for s in dir(k):
                if not s.startswith("_"):
                    ll.append(s)
        self.addmember(m, ll)

    def toStr(self, lv=0, mx=130):

        yield lv * "\t" + f"class {self.name}({str(self.sp)[8:-2]}):"
        for i in self.docs(lv):
            yield i

        for v in self.dcts():
            for i in v.toStr(lv + 1):
                yield i


class mdDscp(pyibase):
    def __init__(self, m: types.MethodDescriptorType) -> None:
        super().__init__()
        assert isinstance(m, types.MethodDescriptorType)
        self.doc = m.__doc__
        self.name = m.__name__

    def toStr(self, lv: int = 0, mx: int = 130):
        yield lv * "\t" + f"def {self.name}(self,*args,**kw):"
        for i in self.docs(lv):
            yield i
        yield lv * "\t" + "\t" + "..."


class gsDscp(pyibase):
    def __init__(self, m: types.GetSetDescriptorType) -> None:
        super().__init__()
        assert isinstance(m, types.GetSetDescriptorType)
        self.doc = m.__doc__
        self.name = m.__name__

    def toStr(self, lv: int = 0, mx: int = 130):

        yield lv * "\t" + f"@property"
        yield lv * "\t" + f"def {self.name}(self):"
        for i in self.docs(lv):
            yield i
        yield lv * "\t" + "\t" + "..."

        yield lv * "\t" + f"@{self.name}.setter"
        yield lv * "\t" + f"def {self.name}(self,value):..."
        yield ""


class mmDscp(pyibase):
    def __init__(self, m: types.MemberDescriptorType) -> None:
        super().__init__()
        assert isinstance(m, types.MemberDescriptorType)
        self.doc = m.__doc__
        self.name = m.__name__
        self._tp = type(m).__name__

    def toStr(self, lv: int = 0, mx: int = 130):
        yield lv * "\t" + f"{self.name}:{self._tp}=..."
        for i in self.docs(lv):
            yield i


class bmDscp(pyibase):
    def __init__(
        self, m: "types.MemberDescriptorType |types.BuiltinMethodType"
    ) -> None:
        super().__init__()
        assert isinstance(m, types.BuiltinFunctionType) and isinstance(
            m, types.BuiltinMethodType
        )
        self.doc = m.__doc__
        self.name = m.__name__

    def toStr(self, lv: int = 0, mx: int = 130):
        yield lv * "\t" + f"def {self.name}(self,*args,**kw):"
        for i in self.docs(lv):
            yield i
        yield lv * "\t" + "\t" + "..."


class nxcs(pyibase):
    def __init__(self, m, name="") -> None:
        super().__init__()
        _md = m.__class__.__module__
        assert "NXOpen" in str(_md)
        self.doc = m.__doc__
        self.name = m.__name__ if hasattr(m, "__name__") else name
        self.attp = str(m.__class__.__name__)

    def toStr(self, lv=0, mx=130):

        yield lv * "\t" + f'{self.name}:"{self.attp}"=...'
        for i in self.docs(lv - 1):
            yield i


class mainModules(pyibase):
    def __init__(
        self,
    ) -> None:
        super().__init__()
        m = NXOpen
        self.doc = m.__doc__
        self.name = m.__name__
        self.addmember(m)
        for i in pyibase.ecpts:
            self.chdtps[i] = basetps(getattr(NXOpen, i), i)
        for k, v in imp_mds.items():
            self.chdmdls[k] = mdls(v)

    def pyi(self):
        mm = self
        if not os.path.exists("./NXOpen/"):
            os.mkdir("./NXOpen")

        if not os.path.exists("./NXOpen/clss/"):
            os.mkdir("./NXOpen/clss/")

        p11 = "./NXOpen/"
        p22 = os.path.join(p11, "clss/")

        with open(os.path.join(p11, "__init__.py"), "w", encoding="utf8") as f:
            m: mdls
            for v in mm.chdmdls.values():
                m = v
                mn = m.name.split(".")[-1]
                mName = mn + ".pyi"
                with open(os.path.join(p11, mName), "w") as f2:
                    for _s in m.toStr():
                        f2.write(_s + "\n")

                f.write(f"from .{mn} import {mn} as {mn}" + "\n")
            f.write(f"from ._nxopen import *\n")

            with open(os.path.join(p11, "_nxopen.pyi"), "w", encoding="utf8") as f2:
                m2: tps
                f2.write("import NXOpen")
                for k, v in mm.chdtps.items():
                    m2 = v
                    nn = m2.name
                    f2.write(f"from .clss.{nn} import {nn} as {nn}" + "\n")
                    with open(
                        os.path.join(p22, f"{nn}.pyi"), "w", encoding="utf8"
                    ) as f3:
                        for _s in m2.toStr():
                            f3.write(f"{_s}\n")


if __name__ == "__main__":

    def main():
        mainModules().pyi()

    main()

标签:__,.__,name,vscode,self,yield,lv,python,二次开发
来源: https://www.cnblogs.com/unm001/p/16259771.html