##嵌入式 Python

0 关注者 · 42 帖子

嵌入式 Python 是指将 Python 编程语言集成到 InterSystems IRIS 内核中,允许开发者使用 Python 对数据进行操作并为服务器端应用程序开发业务逻辑。

文档

文章 Lilian Huang · 十一月 6, 2025 7m read

Interoperability on Python (IoP) 是一个概念验证项目,旨在展示与 Python 优先方式相结合时 InterSystems IRIS Interoperability Framework 的强大功能。IoP 利用Embedded Python(嵌入式 Python,InterSystems IRIS 的一个功能)使开发者能够用 Python 编写互操作性组件,从而可以与强大的 IRIS 平台无缝集成。本指南专为初学者编写,全面介绍了 IoP、其设置以及创建第一个互操作性组件的操作步骤。 阅读完本文,您将能够清楚地了解如何使用 IoP 构建可扩缩、基于 Python 的互操作性解决方案。

0
0 13
InterSystems 官方 Claire Zheng · 六月 20, 2025

InterSystems 宣布 InterSystems IRIS、InterSystems IRIS for Health 和 HealthShare Health Connect 2025.1 正式发布

2025.1 版的 InterSystems IRIS® 数据平台、InterSystems IRIS® for HealthTMHealthShare® Health Connect 现已正式发布 (GA)。 这是扩展维护 (EM) 版本。

版本亮点

在这个激动人心的版本中,用户可以期待一些新功能和增强,包括:

  1. 高级向量搜索功能
  2. 增强的商业智能
    • IRIS BI 多维数据集构建和同步中的自动依赖项分析,确保复杂多维数据集依赖项中的一致性和完整性。
  3. 改进的 SQL 和数据管理
    • 引入了标准 SQL 分页语法 (LIMIT... OFFSET..., OFFSET... FETCH...)。
    • 新的 LOAD SQL 命令,可以简化 DDL 语句的批量导入。
    • 增强的 ALTER TABLE 命令,可以在行布局和列布局之间无缝转换。
  4. 优化的数据库操作
    • 日志记录大小更小,效率更高。
    • 数据库压缩速度更快,尤其是对于具有大量大字符串内容的数据库。
    • 将新数据库添加到镜像时的自动化程度更高。
    • 用于 ECP 管理任务的新命令行实用工具。
  5. 更高的安全合规性
    • 支持符合 FIPS 140-3 标准的加密库。
  6. 现代化的互操作性用户界面
    • 选择参与经过改进的生产配置和 DTL 编辑器体验,其中包含源代码控制集成、VS Code 兼容性、增强的筛选功能、分屏视图等。请参阅此开发者社区文章,详细了解如何选择参与并提供反馈。
  7. 更多的医疗保健功能
    • 高效的批量 FHIR 引入和调度,包括完整性检查和资源管理。
    • 增强的 FHIR 批量访问和经过改进的 FHIR 搜索操作。
  8. 新的开发者体验功能
  9. 通过 OpenTelemetry 提高可观测性
    • 在 IRIS 中引入了跟踪功能,有助于详细观测 Web 请求和应用程序的性能。

请通过开发者社区分享您的反馈,以便我们可以共同打造更出色的产品。

文档

访问以下链接,可以详细了解所有着重介绍的功能:

此外,请查看升级影响核对清单,轻松了解升级到此版本时需要注意的所有变更。

尤其是,请注意 InterSystems IRIS 2025.1 引入了新的日志文件格式版本,该格式与早期版本不兼容,因而给混合版本的镜像设置带来了一定的限制。 请参阅相应的文档了解更多详细信息。

抢先体验计划 (EAP)

目前提供多个 EAP。 请查看此页面并注册您感兴趣的 EAP。

下载软件

一如既往,扩展维护 (EM) 版本提供了适用于所有受支持平台的经典安装包,以及 Docker 容器格式的容器镜像。

经典安装包

安装包可以从 WRC 的 InterSystems IRIS 页面(对于 InterSystems IRIS 和 InterSystems IRIS for Health)和 WRC 的 HealthShare 页面(对于 Health Connect)获取。 您也可以在评估服务网站中找到工具包。

可用性和软件包信息

此版本提供了适用于所有受支持平台的经典安装包,以及 Docker 容器格式的容器镜像。有关完整列表,请参阅“支持的平台”文档

此扩展维护版本的内部版本号为 2025.1.0.223.0

容器镜像可以从 InterSystems 容器注册表中获取。 容器被标记为 2025.1latest-em

0
0 76
InterSystems 官方 Claire Zheng · 六月 19, 2025 4m read

互操作性用户界面现在包括可以在所有互操作性产品中使用的 DTL 编辑器生产配置应用程序的现代化用户体验。您可以在现代化视图与标准视图之间切换。所有其他互操作性屏幕仍采用标准用户界面。请注意,仅对这两个应用程序进行了更改,我们在下面确定了当前可用的功能。

要在升级前试用新屏幕,您可以点击这里,从我们的社区工具包网页中下载 2025.1 版:https://evaluation.intersystems.com/Eval/。请观看“学习服务”中的简短教程构建集成:一种新的用户体验,了解对这些屏幕进行的用户增强!

生产配置 - 配置任务简介
  • 生产配置:在以下版本的生产配置中受支持:
    • 创建/编辑/复制/删除主机
    • 停止/启动主机
    • 编辑生产设置
    • 停止/启动生产
  • 源代码控制集成:支持上述配置功能的源代码控制集成。
  • 分屏 视图:用户可以直接从“生产配置”屏幕打开“规则编辑器”和“DTL 编辑器”,在分屏视图中查看和编辑产品中包含的规则和转换。
  • 增强的筛选功能:使用顶部的搜索框,您可以搜索和筛选各种业务组件,包括多种类别、DTL 和子转换。 使用左侧边栏可以独立于主面板进行搜索,查看各种主机和类别中的搜索结果。
  • 批量编辑主机类别:通过从生产配置中添加主机,您可以为生产添加新类别或编辑现有类别。
  • 可展开路由器:可以展开路由器,内联查看所有规则、转换和连接。
  • 重新设计的主机连接:现在,在选择业务主机时,将呈现直接连接和间接连接,您可以查看消息能够采用的完整路径。 将鼠标悬停在任何出站或入站主机上可以进一步区分连接。如果开启仅显示连接的主机开关,将仅筛选所选主机及其连接。
DTL 编辑器 - DTL 工具简介
  • 源代码控制集成:支持源代码控制集成。
  • VS Code 集成:用户可以在其 VS Code IDE 中查看此版本的 DTL 编辑器。
  • 嵌入式 Python 支持:此版本的 DTL 编辑器现在支持嵌入式 Python。
  • DTL 测试:可以在此版本的 DTL 编辑器中使用 DTL 测试实用工具。
  • 切换面板布局:DTL 编辑器支持侧面到侧面和顶部到底部布局。 点击顶部功能区的布局按钮可以体验此功能。
  • 撤消/重做:用户可以使用撤消/重做按钮撤消和重做所有尚未保存为代码的操作。
  • “生成空段”参数:GENERATEEMPTYSEGMENTS 参数可用于为缺失的字段生成空段。
  • 子转换查看:用户可以点击眼睛图标,在新选项卡中打开子转换 DTL,查看子转换。
  • 滚动
    • 单独滚动:将光标放置在 DTL 的左右两部分(源和目标)其中之一的上方,并用滚轮或触控板垂直移动各段,可以单独滚动各个部分。
    • 联合滚动:将光标放置在图的中间,可以联合滚动源部分和目标部分。
  • 字段自动补全:自动补全适用于:“源”、“目标”和“条件”字段以及源类、源文档类型、目标类、目标文档类型。
  • 顺序编号:使用可视化编辑器,您可以打开和关闭查看每个段的序数和完整路径表达式的功能。
  • 轻松引用:当操作编辑器中的某个字段获得焦点时,在图形化编辑器中双击某个段会在操作编辑器中的当前光标位置插入相应的段引用。
  • 同步:点击可视化编辑器中的一个元素,可以在操作编辑器中高亮显示相应的行。
📣号召性用语📣

如果您有任何反馈,请通过以下途径提供给我们:

  • 跨所有互操作性的新功能:在 Ideas 门户中输入想法,或在 InterSystems Ideas 门户中参与其他想法。 对于新想法,请在您的帖子上添加“互操作性”标签或对列表中已提出的功能进行投票!
  • 💻跨所有互操作性的一般用户体验反馈:请在下面输入您的反馈或参与其他评论。
  • 🗒对现代化应用程序的建议/反馈(如上所述):请在下面输入您的反馈或参与其他评论。

请考虑利用 Global Masters 的机会,与团队进行互动,参与不公开的指导反馈会议,并获得积分! 点击此处,通过 Global Masters 报名参加这些会议。

如果您希望以私人形式提供任何其他反馈,请通过电子邮件将您的想法或问题发送至:ux@intersystems.com  
 

0
0 47
文章 Lilian Huang · 四月 16, 2025 7m read

Hi 大家好
在本文中,我讲介绍我的应用 iris-AgenticAI .

代理式人工智能的兴起标志着人工智能与世界互动方式的变革性飞跃--从静态响应转变为动态、目标驱动的问题解决方式。参看 OpenAI’s Agentic SDK ,  OpenAI Agents SDK使您能够在一个轻量级、易用且抽象程度极低的软件包中构建代理人工智能应用程序。它是我们之前的代理实验 Swarm 的生产就绪升级版。

该应用展示了下一代自主人工智能系统,这些系统能够进行推理、协作,并以类似人类的适应能力执行复杂任务。

应用功能

  • Agent Loop 🔄 一个内置循环,可自主管理工具的执行,将结果发回 LLM,并迭代直至任务完成。
  • Python-First 🐍 利用本地 Python 语法(装饰器、生成器等)来协调和连锁代理,而无需外部 DSL。
  • Handoffs 🤝 通过在专业代理之间委派任务,无缝协调多代理工作流程。
  • Function Tools ⚒️ 用 @tool 修饰任何 Python 函数,可立即将其集成到代理的工具包中。
  • Vector Search (RAG) 🧠 原生集成向量存储(IRIS),用于 RAG 检索。
  • Tracing 🔍 内置跟踪功能,可实时可视化、调试和监控代理工作流(想想 LangSmith 的替代方案)。
  • MCP Servers 🌐 通过 stdio 和 HTTP 支持模型上下文协议(MCP),实现跨进程代理通信。
  • Chainlit UI 🖥️ 集成 Chainlit 框架,可使用最少的代码构建交互式聊天界面。
  • Stateful Memory 🧠 跨会话保存聊天历史、上下文和代理状态,以实现连续性和长期任务。
0
0 118
文章 Lilian Huang · 四月 10, 2025 6m read

社区朋友们好,

传统的基于关键词的搜索方式在处理具有细微差别的领域特定查询时往往力不从心。而向量搜索则通过语义理解能力,使AI智能体能够根据上下文(而非仅凭关键词)来检索信息并生成响应。

本文将通过逐步指导,带您创建一个具备代理能力的AI RAG(检索增强生成)应用程序。

实现步骤:

  1. 添加文档摄取功能
    • 自动获取并建立文档索引(例如《InterSystems IRIS 2025.1版本说明》)
    • 实现向量搜索功能
  2. 构建向量搜索智能体
  3. 移交至主智能体(分流处理)
  4. 运行智能体

1. Create Agent Tools 添加文档摄取功能

Implement Document Ingestion: Automated ingestion and indexing of documents 


1.1 - 以下是实现文档摄取工具的代码:

defingestDoc(self):#Check if document is defined, by selecting from table#If not defined then INGEST document, Otherwise back
        embeddings = OpenAIEmbeddings()	
        #Load the document based on the fle type
        loader = TextLoader("/irisdev/app/docs/IRIS2025-1-Release-Notes.txt", encoding='utf-8')      
        
        documents = loader.load()        
        text_splitter = RecursiveCharacterTextSplitter(chunk_size=400, chunk_overlap=0)
        
        texts = text_splitter.split_documents(documents)
                       
        #COLLECTION_NAME = "rag_document"
        db = IRISVector.from_documents(
            embedding=embeddings,
            documents=texts,
            collection_name = self.COLLECTION_NAME,
            connection_string=self.CONNECTION_STRING,
        )

        db = IRISVector.from_documents(embedding=embeddings,documents=texts, collection_name = self.COLLECTION_NAME, connection_string=self.CONNECTION_STRING,)

向量搜索智能体(Vector Search Agent)能够自动完成文档的摄取(ingest)索引构建(index), 该新功能在InterSystems IRIS 2025.1的数据资源文件夹里) 至 IRIS 向量存储, 只有当数据尚未存在时,才执行该操作。


运行以下查询以从向量存储中获取所需数据:

SELECTid, embedding, document, metadata
FROM SQLUser.AgenticAIRAG


1.2 - 实现向量搜索功能


以下代码为智能体提供了搜索能力:

defragSearch(self,prompt):#Check if collections are defined or ingested done.# if not then call ingest method
        embeddings = OpenAIEmbeddings()	
        db2 = IRISVector (
            embedding_function=embeddings,    
            collection_name=self.COLLECTION_NAME,
            connection_string=self.CONNECTION_STRING,
        )
        docs_with_score = db2.similarity_search_with_score(prompt)
        relevant_docs = ["".join(str(doc.page_content)) + " "for doc, _ in docs_with_score]
        
        #Generate Template
        template = f"""
        Prompt: {prompt}
        Relevant Docuemnts: {relevant_docs}
        """return template


分流代理处理传入的用户查询,并将其委托给矢量搜索代理,后者执行语义搜索操作,以检索最相关的信息。

0
0 97
公告 Claire Zheng · 九月 11, 2024

HI 各位开发者们,

📅2024年9月23日🕑14:00-15:30🕞,InterSystems将举办线上研讨会,点击🔔此处🔔报名参会。

此次研讨会以“面向未来的数据平台——InterSystems IRIS五大亮点提速数据潜力挖掘与AI应用”为主题,帮助您了解InterSystems IRIS数据平台的五大亮点:

  • 使用InterSystems IRIS for Health进行FHIR开发
  • 使用Python进行互操作Production开发
  • InterSystems IRIS列存储
  • InterSystems IRIS外部表(Foreign Table)
  • InterSystems IRIS向量和基于向量检索的患者相似度匹配
2
0 115
文章 Michael Lei · 八月 1, 2024 4m read

随着 IRIS 中向量数据类型和向量搜索功能的引入,应用程序的开发正在开启一个充满各种可能性的全新世界,其中一个应用程序示例是我最近在巴伦西亚卫生局的一次公开竞赛中看到的应用程序,他们要求提供一种工具,能够使用 AI 模型协助进行 ICD-10 编码。

我们如何实现与所要求的应用程序类似的应用程序? 我们来看看需要什么:

  1. ICD-10 代码列表,我们将使用它作为 RAG 应用程序的上下文,在纯文本中搜索诊断结果。
  2. 经过训练的模型,它会将文本向量化,我们将在其中查找 ICD-10 代码中的对应项。
  3. Python 库,用于对 ICD-10 代码和文本进行摄取和向量化。
  4. 一个支持文本的友好前端,我们会在其中查找可能的诊断结果。
  5. 从前端接收的请求的编排。

IRIS 为我们提供哪些功能来满足上述需求?

  1. CSV 导入,可以使用 RecordMapper 功能,也可以直接使用嵌入式 Python。
  2. 嵌入式 Python 使我们能够实现使用所选模型生成向量所需的 Python 代码。
  3. 发布将从前端应用程序调用的 REST API。
  4. 互操作性生产,以允许在 IRIS 中跟踪信息。

我们只需要看看开发的示例:

d[IA]gnosis

在本文中,您可以访问开发的应用程序,在后续文章中,我们将详细了解如何实现每个功能,包括模型的使用、向量的存储和向量搜索的使用。

我们来看看这个应用程序:

导入 ICD-10 代码

在配置屏幕中,我们知道了 CSV 文件必须使用的格式,以符合我们要导入的 ICD-10 代码。 加载和向量化过程会占用大量时间和资源,因此,为了防止所需空间超出分配的 RAM,在部署 Docker 容器时,不仅配置了 Docker 可用的 RAM 内存,还配置了磁盘存储器:

# iris  iris:    init:true    container_name:iris    build:      context:.      dockerfile:iris/Dockerfile    ports:      -52774:52773      -51774:1972    volumes:    -./shared:/shared    environment:    -ISC_DATA_DIRECTORY=/shared/durable    command:--check-capsfalse--ISCAgentfalse    mem_limit:30G    memswap_limit:32G

包含 ICD-10 代码的文件位于项目路径 /shared/cie10/icd10.csv 中,达到 100% 后,即可使用该应用程序。

在我们的应用程序中,我们定义了两个不同的诊断结果编码功能,一个基于系统中接收到的 HL7 消息,另一个基于纯文本。

从 HL7 中捕获诊断结果

项目中包含一些准备进行测试的 HL7 消息,只需将 /shared/hl7/messagesa01_en.hl7 文件复制到 /shared/HL7In 文件夹,相关的生产就会负责从中提取诊断结果,并显示在 Web 应用程序中:

在诊断结果请求屏幕中,我们可以看到通过 HL7 消息收到的所有诊断结果。 要将它们编码为 ICD-10,我们只需点击放大镜以显示与收到的诊断结果最接近的 ICD-10 代码列表:

选择后,我们将在列表中看到诊断结果及其相关的 ICD-10 代码。 点击带有信封图标的按钮,将使用原始代码生成一条消息,并在诊断结果部分包含所选新代码:

MSH|^~\&|HIS|HULP|EMPI||||ADT^A08|592956|P|2.5.1
EVN|A01|
PID|||1556655212^^^SERMAS^SN~922210^^^HULP^PI||GARCÍA PÉREZ^JUAN^^^||20150403|M|||PASEO PEDRO ÁLVAREZ 1951 CENTRO^^LEGANÉS^MADRID^28379^SPAIN||555283055^PRN^^JUAN.GARCIA@YAHOO.COM|||||||||||||||||N|
PV1||N
DG1|1||O10.91^Unspecified pre-existing hypertension complicating pregnancy^CIE10-ES|Gestational hypertension||A||

可以在路径 /shared/HL7Out 中找到此消息

以纯文本形式显示的诊断结果的屏幕截图

在“文本分析器”选项中,用户可以包含纯文本,并对其进行分析。 该应用程序将按 3 个词形还原的词(去除冠词、代词和其他不太相关的词)构成的元组进行搜索。 分析后,系统将向我们显示相关的带下划线的文本和找到的可能的诊断结果:

执行分析后,可以随时从分析历史记录中进行查询。

分析历史记录

执行的所有分析都会记录下来,可以随时查询,并且能够查看所有可用的 ICD-10 代码:

在下一篇文章中…

我们将看到,如何借助嵌入式 Python,使用特定的 LLM 模型对 ICD-10 代码进行向量化,从而将其用作上下文和自由文本。

如果您有任何疑问或建议,请随时对本文发表评论。

0
0 79
文章 Michael Lei · 三月 21, 2024 2m read

这是在 IRIS 中完全运行向量搜索演示的尝试。
没有外部工具,您需要的只是终端/控制台和管理门户。
特别感谢Alvin Ryanputra作为他的软件包iris-vector-search的基础
灵感和测试数据的来源。
我的软件包基于 IRIS 2024.1 版本,需要注意您的处理器功能。

我尝试用纯 ObjectScript 编写演示。
仅描述向量的计算是在嵌入式Python中完成的
计算 2247 个记录的 384 维向量需要时间。
在我的 Docker 容器中,它正在运行 01:53:14 来完全生成它们。

然后被警告了!
所以我将这一步调整为可重入,以允许暂停向量计算。
每 50 条记录,您就会收到一次停止的提议。
该演示如下所示:

1
0 87
文章 Jingwei Wang · 二月 15, 2024 4m read

大型语言模型(例如 OpenAI 的 GPT-4)的发明和普及掀起了一波创新解决方案浪潮,这些解决方案可以利用大量非结构化数据,在此之前,人工处理这些数据是不切实际的,甚至是不可能的。此类应用程序可能包括数据检索(请参阅 Don Woodlock 的 ML301 课程,了解检索增强生成的精彩介绍)、情感分析,甚至完全自主的 AI 代理等!

在本文中,我想演示如何使用 IRIS 的嵌入式 Python 功能直接与 Python OpenAI 库交互,方法是构建一个简单的数据标记应用程序,该应用程序将自动为我们插入IRIS 表中的记录分配关键字。然后,这些关键字可用于搜索和分类数据,以及用于数据分析目的。我将使用客户对产品的评论作为示例用例。

先决条件

  • 运行的IRIS实例
  • OpenAI API 密钥(您可以在此处创建)
  • 配置好的开发环境(本文将使用VS Code

Review类

让我们首先创建一个 ObjectScript 类,该类将定义客户评论的数据模型。为了简单起见,我们将只定义 4 个 %String 字段:客户姓名、产品名称、评论正文以及我们将生成的关键字。该类应该扩展%Persistent,以便我们可以将其对象保存到磁盘。

0
0 127
文章 Michael Lei · 九月 18, 2023 6m read

如今,关于大语言模型、人工智能等的消息不绝于耳。向量数据库是其中的一部分,并且已经有非IRIS的技术实现了向量数据库。

为什么是向量?

  • 相似性搜索:向量可以进行高效的相似性搜索,例如在数据集中查找最相似的项目或文档。传统的关系数据库是为精确匹配搜索而设计的,不适合图像或文本相似性搜索等任务。
  • 灵活性:向量表示形式用途广泛,可以从各种数据类型派生,例如文本(通过 Word2Vec、BERT 等嵌入)、图像(通过深度学习模型)等。
  • 跨模态搜索:向量可以跨不同数据模态进行搜索。例如,给定图像的向量表示,人们可以在多模式数据库中搜索相似的图像或相关文本。

还有许多其他原因。

因此,对于这次 pyhon 竞赛,我决定尝试实现这种支持。不幸的是我没能及时完成它,下面我将解释原因。

0
0 161
文章 Lilian Huang · 七月 9, 2023 5m read

#Embedded Python #HL7 #InterSystems IRIS for Health

写在回复社区帖子《Python能否动态创建HL7消息》中。

前提条件和设置

使用一个启用了集成的命名空间。
注意:USER命名空间默认不启用互操作性。
如果以下建议创建一个新的互操作性命名空间来探索功能。

# 切换到
ZN "[互操作性名称空间名称]"

# 启动交互式Python shell:
Do $SYSTEM.Python.Shell()

启动脚本

#Load dependencies

import datetime as dt
import uuid

# Cache current time in CCYYMMDDHHMMss format
hl7_datetime_now=dt.datetime.now().strftime('%Y%m%d%H%M%S')

# Create HL7 Message
hl7=iris.cls("EnsLib.HL7.Message")._New()

# Set the doc type
# 2.5.1:ORU_R01 - Unsolicited transmission of an observation message
hl7.PokeDocType("2.5.1:ORU_R01")

这些信息的结构可以从管理门户中获取

0
0 294
文章 Michael Lei · 七月 3, 2023 4m read

你好社区
在本文中,我将介绍我的应用程序irisChatGPT ,它是基于LangChain Framework构建的。
首先,让我们对框架进行一个简单的概述。

全世界都在谈论ChatGPT以及大型语言模型 (LLM) 如何变得如此强大,并且表现超出预期,提供类似人类的对话。这只是将其应用于每个企业和每个领域的开始!

0
0 379
公告 Claire Zheng · 六月 19, 2023

大家好!

InterSystems Grand Prix 2023 结合了 InterSystems IRIS 数据平台的所有主要功能!

因此,我们邀请您使用以下功能并收集额外的技术奖励,以帮助您赢得奖品!

如下:

  • LLM AI 或 LangChain 用法:Chat GPT、Bard 等 - 6
  • InterSystems FHIR SQL Builder- 5
  • InterSystems FHIR-3
  • IntegratedML - 4
  • Native API - 3
  • 嵌入式 Python - 4
  • 互操作性 - 3
  • 生产扩展(PEX)- 2
  • 自适应分析 (AtScale) Cube的使用 - 3
  • Tableau、PowerBI、Logi 的使用 - 3
  • InterSystems IRIS BI - 3
  • 列索引使用 - 1
  • Docker 容器使用 - 2
  • ZPM 包部署 - 2
  • 在线演示 - 2
  • 单元测试 - 2
  • 实施 InterSystems Community Idea中的创意 - 4
  • 在开发者社区发布的第一篇文章 - 2
  • 在开发者社区发布的第二篇文章 - 1
  • 代码质量通过 - 1
  • 第一次贡献 - 3
  • YouTube 上的视频 - 3
0
1 164
文章 Jingwei Wang · 六月 8, 2023 1m read

在InterSystems IRIS中重新加载更新后的Python模块的方式和直接使用Python 重新加载模块的方式是一样的。

Python3.4 之后到版本中,直接使用Python 重新加载模块的方式如下:

import importlib
​
importlib.reload(module)

同样,在在InterSystems IRIS中重新加载Python模块的方式与其没有区别,示例如下:

ClassMethod Hello() As %Status
{
 Set sc = $$$OK
 Set sm = ##class(%SYS.Python).Import("sample")
 Set importlib = ##class(%SYS.Python).Import("importlib")
 do importlib.reload(sm)
 write sm.hello()
 Return sc
}
​
0
0 129
文章 Lilian Huang · 四月 28, 2023 8m read

     

嗨社区,
在本文中,我将演示 InterSystems Embedded Python 的用法,我们将涵盖以下主题:

  • 1-嵌入式Python概述
  • 2-嵌入式Python的使用
    • 2.1- 从 ObjectScript 使用 Python 库
    • 2.2- 从 Python 调用 InterSystems API
    • 2.3- 一起使用 ObjectScript 和 Python
  • 3-使用python内置函数
  • 4-Python 模块/库
  • 5 个嵌入式 Python 用例
  • 6-总结

我们从概述开始
 

1-嵌入式Python概述

嵌入式 Python 是 InterSystems IRIS 数据平台的一项功能,它允许 Python 开发人员完全直接地访问 InterSystems IRIS 中的数据和功能。

InterSystems IRIS 带有一种名为 ObjectScript 的强大内置编程语言,可在数据平台内部进行解释、编译和运行。

0
0 275
文章 Michael Lei · 三月 21, 2023 3m read

InterSystems IRIS 是一个高性能、可靠且可扩展的数据平台,用于为医疗保健、金融服务和其他行业构建和部署关键任务应用程序。它提供了广泛的功能,包括数据管理、集成、分析等。

IRIS 提供的功能之一是能够将 Python 代码嵌入到 ObjectScript 代码中。这意味着您可以在 IRIS 应用程序中使用 Python 库和函数,让您可以访问大量的工具和资源。在本文中,我们将了解如何在 InterSystems IRIS 中使用嵌入式 Python。

设置嵌入式 Python

在 IRIS 中开始使用嵌入式 Python 之前,您需要设置环境。这涉及安装 Python 解释器和配置 IRIS 以识别它。

第一步是安装 Python。您可以从官方网站 ( https://www.python.org/downloads/ ) 下载最新版本的 Python。安装 Python 后,需要将其添加到系统的 PATH 环境变量中。这允许 IRIS 找到 Python 解释器。

接下来,您需要配置 IRIS 以识别 Python。为此,您需要创建一个 Python 网关。网关是一个在 IRIS 之外运行的进程,充当 IRIS 和 Python 之间的桥梁。

要创建网关,请打开一个终端窗口并导航到 Python 安装目录。然后运行以下命令:

python -m irisnative

0
1 222
文章 Jingwei Wang · 一月 19, 2023 6m read

什么是网页抓取:

简单来说,网络抓取网络收获网络数据提取是从网站收集大数据(非结构化)的自动化过程。用户可以根据需要提取特定站点上的所有数据或特定数据。收集的数据可以以结构化格式存储以供进一步分析。

什么是网页抓取? — 詹姆斯·勒
网页抓取涉及的步骤:

  1. 找到您要抓取的网页的 URL
  2. 通过检查选择特定元素
  3. 编写代码获取被选元素的内容
  4. 以需要的格式存储数据

就这么简单!

用于网络抓取的流行库/工具是:

  • Selenium – 用于测试 Web 应用程序的框架
  • BeautifulSoup – 用于从 HTML、XML 和其他标记语言中获取数据的 Python 库
  • Pandas – 用于数据操作和分析的 Python 库


什么是Beautiful Soup?

Beautiful Soup 是一个纯 Python 库,用于从网站中提取结构化数据。它允许您解析来自 HTML 和 XML 文件的数据。它充当辅助模块,并以与使用其他可用开发人员工具以网页交互的方式与 HTML 交互。

0
0 296
文章 Jingwei Wang · 一月 19, 2023 6m read

Python 已成为世界上使用最广泛的编程语言(来源:https://www.tiobe.com/tiobe-index/),SQL 作为数据库语言继续引领潮流。 Python 和 SQL 一起工作以提供 SQL 单独无法提供的新功能不是很好吗?毕竟,Python 拥有超过 380,000 个已发布的库(来源:https://pypi.org/),它们具有非常有趣的功能,可以在 Python 中扩展您的 SQL 查询。本文详细介绍了如何使用嵌入式 Python 在 InterSystems IRIS 数据库中创建新的 SQL 存储过程。

用作示例的 Python 库

本文将使用两个非常有用的库:Geopy 和 Chronyk。

Geopy 是一个用于将地理编码(地址和地理坐标的限定)应用于地址数据的库。有了它,就可以从街道名称中获取邮局格式的邮政编码和完整地址。非常有用,因为许多记录都有地址。

Chronyk 用于使用人类语言处理日期和时间。这非常有用,因为在内部,对于 IRIS 和 Python,日期是一个数字,表示自初始日期以来经过的时间量。对于人类来说,日期是 7 月 20 日,或者昨天,或者明天,或者两个小时前。 Chronyk 接受接收这样的日期,然后将其转换为通用日期格式。

InterSystems IRIS 中的 Python 支持

0
0 174
文章 Lilian Huang · 一月 19, 2023 4m read

动机

这个项目是在我考虑如何通过Embedded Python让Python代码自然地处理IRIS globals所提供的可扩展的存储和高效的检索机制时想到的。

我最初的想法是使用globals创建一种Python字典的实现,但很快我就意识到,我应该首先处理对象的抽象问题。

所以,我开始创建一些可以包装Python对象的Python类,在globals中存储和检索它们的数据,也就是说,在IRIS globals中序列化和反序列化Python对象。

它是如何工作的?

像 ObjectScript 的%DispatchGetProperty()%DispatchSetProperty() 和%DispatchMethod()一样, Python 有委托对象的属性和方法调用的方式。

当你设置或获取一个对象属性时,Python 解释器让你通过方式 __setattr__(self, name, value) 和 __getattr(self, name)__来截获这个操作。

请看这个相当基本的例子。

0
0 170
文章 Michael Lei · 十二月 13, 2022 7m read

嵌入式 Python 模板

今天你们分享一个简单的嵌入式 Python 模板,我建议将其作为任何使用 InterSystems IRIS 并将使用嵌入式 Python 的通用项目的起点。

功能:

  • 随时可用的嵌入式 Python;
  • 3 种嵌入式 Python 开发方式示例;
  • 随时可用的 VSCode 开发;
  • 支持 Docker;
  • 支持在线演示;
  • 随时可用的 ZPM 优先开发。

下面讨论一下这些功能!

我们先来谈谈嵌入式 Python。 此功能在 InterSystems IRIS 2021.2 中提供,它允许使用 InterSystems IRIS 通过 Python 开发解决方案。 IRIS 2021.2 及以上版本允许使用 InterSystems IRIS 在共享内存环境中执行 Python 脚本,这为 Python 开发者在使用代码与数据相近的数据库时提供了独特的选项。 

3 种使用嵌入式 Python 进行开发的模式

从 ObjectScript 调用 Python 库

此操作因 %SYS.Python 类而变为可能,该类允许导入 Python 库并通过 ObjectScirpt 调用 Python。 文档示例。 请查看以下代码:

<span class="hljs-keyword">ClassMethod</span> Today() <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Status</span>
{
  <span class="hljs-keyword">Set</span> sc = <span class="hljs-built_in">$$$OK</span>
  <span class="hljs-keyword">Set</span> dt = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%SYS.Python</span>).Import(<span class="hljs-string">"datetime"</span>)
  <span class="hljs-keyword">write</span> dt.date.today().isoformat()
  <span class="hljs-keyword">Return</span> sc
}

使用 Python 编写 ObjectScript 类方法

事实上,现在开发者可以使用纯 Python 在方法签名和代码中添加 [Language=python] 标签。 还有一个辅助 Python 库“iris”,可以用于引用 ObjectScript 类和全局变量。 文档示例、示例代码:

ClassMethod CreateRecordPython(propValue As %VarString, ByRef id As %Integer) [ Language = python ]
{
    <span class="hljs-keyword">import</span> iris
    obj=iris.cls(__name__)._New()
    obj.Test=propValue
    sc=obj._Save()
    id=obj._Id()
    <span class="hljs-keyword">return</span> sc
}

使用纯 Python 编写 InterSystems IRIS 解决方案代码

这是开发者可以选择的第三种处理 IRIS 的方式。  这里,Python 脚本需要连接到 IRIS,此操作可以通过环境变量和设为“On”的 CallIn 服务来完成,请参见下面的详细信息。 设置完后,使用 IRIS 在共享内存中执行 Python 脚本。 在这里,“iris”库也非常有用。 文档示例。 

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_rec</span><span class="hljs-params">(var)</span>:</span>
    obj=iris.cls(<span class="hljs-string">'dc.python.PersistentClass'</span>)._New()
    obj.Test=var
    obj._Save()
    id=obj._Id()
    <span class="hljs-keyword">return</span> id

<span class="hljs-comment"># test record creation</span>
<span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime
now=str(datetime.now())
print(<span class="hljs-string">"Creating new record in dc.python.PersistentClass"</span>)
print(create_rec(now))

<span class="hljs-comment">## run SQL and print data</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">run_sql</span><span class="hljs-params">(query)</span>:</span>
    rs=iris.sql.exec(query)
    <span class="hljs-keyword">for</span> idx, row <span class="hljs-keyword">in</span> enumerate(rs):
        print(<span class="hljs-string">f"[<span class="hljs-subst">{idx}</span>]: <span class="hljs-subst">{row}</span>"</span>)

query=<span class="hljs-string">"Select * from dc_python.PersistentClass"</span>
print(<span class="hljs-string">"Running SQL query "</span>+query)
run_sql(query)

支持 Docker

模板仓库在容器中运行 IRIS,并设置嵌入式 Python 调整所需的所有内容。 

环境变量。 嵌入式 Python 需要设置特定的环境变量来连接到 IRIS 并运行 Python 脚本。 下面是 dockerfile 中有帮助的设置:

# init Python env
ENV PYTHON_PATH=/usr/irissys/bin/irispython
ENV SRC_PATH=/irisrun/repo
ENV IRISUSERNAME "SuperUser"
ENV IRISPASSWORD "SYS"
ENV IRISNAMESPACE "USER"

此外,嵌入式 Python 需要将 CallIn 服务设为“on”,此操作在构建 docker 的阶段在 iris.script 中完成:

<span class="hljs-comment">; enabling callin for Embedded Python</span>
    <span class="hljs-keyword">do</span> <span class="hljs-keyword">##class</span>(Security.Services).Get(<span class="hljs-string">"%Service_CallIn"</span>,.prop)
    <span class="hljs-keyword">set</span> prop(<span class="hljs-string">"Enabled"</span>)=<span class="hljs-number">1</span>
    <span class="hljs-keyword">set</span> prop(<span class="hljs-string">"AutheEnabled"</span>)=<span class="hljs-number">48</span>
    <span class="hljs-keyword">do</span> <span class="hljs-keyword">##class</span>(Security.Services).Modify(<span class="hljs-string">"%Service_CallIn"</span>,.prop)

另外,您的解决方案可能需要安装一些 Python 库。 这通过仓库根目录中的 requirements.txtdockerfile 中的 pip3 调用来实现:

pip3 install -r requirements.txt && \

随时可用的 VSCode 开发

使用 docker 在 VSCode 中开发非常方便。 如果想要在 docker IRIS 解决方案中使用嵌入式 Python 进行开发,VSCode 需要切换到 Devcontainer 模式。 为此,将 devcontainer.json 文件添加到 .devcontainer 文件夹中。 该文件描述了需要使用的 docker 服务(本例中为 iris),这可以帮助在 VSCode 中运行 Python 脚本,这些脚本将由在容器中运行的 IRIS 使用的 Python 引擎提供服务。 devcontainer.json 文件还有一个部分,其中说明了需要在容器模式下使用哪些扩展

"extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "intersystems-community.vscode-objectscript",
        "intersystems.language-server",
        "intersystems-community.servermanager",
        "ms-vscode.docker"
    ],

通过 ZPM 安装嵌入式 Python 解决方案

此模板被设置为“ZPM 优先”开发仓库。 这意味着所有开发代码都已在 module.xml 中介绍,并且每次构建 docker 镜像时都作为 ZPM 模块安装,开发者每次编码时都在 iris.script 中使用以下行开头:

zpm "load /home/irisowner/irisbuild/ -v":1:1

ZPM 模块中还介绍了嵌入式 Python 代码,它通过 FILECOPY 进行安装:

<FileCopy Name="python/" Target="${libdir}python/"/>

此表达式表示,我们想要将所有 Python 脚本打包在仓库中的 /python 文件夹下,并将其安装在目标 IRIS 安装程序的 libdir 的 python/ 文件夹中。 如果将 Python 脚本复制到 ${libdir}python/ 文件夹下,则可以在目标 IRIS 机器中通过 ObjectScirpt 或 Python 对其进行导入调用。

注意: 确保您的文件夹名称唯一,以免意外替换其他 Python 代码。

希望该模板对您有用。 欢迎提供反馈,尤其是拉取请求!

0
0 242
文章 Weiwei Gu · 九月 28, 2022 3m read

Hi Developers,

嗨,各位开发者们:

各位都知道,Python是一个庞大而强大的生态系统,包含了成千上万的库和包,特别是在数据科学方面。

因此,我想首次尝试使用IRIS最近的一项功能--嵌入式Python,简单地导入一个名为datetime的Python库,生成带有时间戳成分的数据,并在InterSystems IRIS for Health Data Platform中持久化。同样的方法在IRIS数据平台上也可以使用。

1
0 172
文章 Jingwei Wang · 九月 6, 2022 4m read

 

在Windows中,InterSystems IRIS 会将Python引擎一起安装在安装目录中,可以将Python的代码在InterSystems IRIS内核中运行,允许Python代码与ObjectScript代码混合运行,以获得最佳开发性能。一般基于UNIX的操作系统会自带一个Python,所以不会随InterSystems IRIS安装包自动安装Python引擎。

InterSystems IRIS 2021.2 以上的版本中才支持Embedded Python,其余版本不支持使用Embedded Python

步骤 - Windows

0
0 763
文章 Muhammad Waseem · 八月 11, 2022 2m read

嗨社区,

这篇文章公开介绍我的 iris-fhir-client 客户端应用。

 iris-fhir-client 可以可以借助嵌入式 python 连接到任何开放的 FHIR 服务器 fhirpy 图书馆.

通过终端和使用 CSP Web 应用程序获取资源信息。

0
0 200
文章 Michael Lei · 八月 9, 2022 23m read

在这篇文章中,你可以访问InterSystems开发者社区中与学习InterSystems IRIS最相关主题的文章库。找到按机器学习、嵌入式Python、JSON、API和REST应用、管理和配置InterSystems环境、Docker和云、VSCode、SQL、分析/BI、全局、安全、DevOps、互操作性、Native API排列的顶级发表的文章。快来享受学习的乐趣吧!

机器学习

机器学习是建立先进的数据分析和自动化人工活动的一种必要的技术,具有很好的效率。它可以创建认知模型,从现有的数据中学习,并根据其自我调整的算法进行预测、概率计算、分类、识别和 "非创造性 "的人类活动的自动化。

在所有情况下,InterSystems IRIS作为一个数据平台和环境来创建、执行、提供和使用这些机器学习模型。IRIS能够从SQL命令(IntegratedML)中使用ML,使用嵌入式Python和PMML(预测模型标记语言)来执行ML。你可以在以下文章中查看它的功能:

1
0 290
文章 姚 鑫 · 七月 18, 2022 6m read

第九章 使用嵌入式 Python (六)

异常处理

IRIS 异常处理程序可以处理 Python 异常并将它们无缝传递给 ObjectScript。在前面的 Python 库示例的基础上,如果尝试使用不存在的文件调用 canvas.drawImage(),并在 ObjectScript 中捕获异常,会看到以下内容:

USER>try { do canvas.drawImage("C:\Sample\bad.png", 150, 600) } catch { write "Error: ", $zerror, ! }
Error: <THROW> *%Exception.PythonException <THROW> 230 ^^0^DO canvas.drawImage("W:\Sample\isc.png", 150, 600) 
<class 'OSError'>: Cannot open resource "W:\Sample\isc.png" -

这里 <class 'OSError'>: Cannot open resource "W:\Sample\isc.png"是从 Python 传回的异常。

字节和字符串

Python 对“字节”数据类型的对象和字符串(表示字符串的 UTF-8 字节序列)进行了明确区分,它们是简单的 8 位字节序列。在 Python 中,字节对象永远不会以任何方式进行转换,但字符串可能会根据主机操作系统使用的字符集进行转换,例如 Latin-1

IRIS 不区分字节和字符串。虽然 IRIS 支持 Unicode 字符串 (UCS-2/UTF-16),但任何包含小于 256 的值的字符串都可以是字符串或字节。出于这个原因,在将字符串和字节传入和传出 Python 时,以下规则适用:

  • IRIS 字符串假定为字符串,并在从 ObjectScript 传递到 Python 时转换为 UTF-8
  • Python 字符串在传回 ObjectScript 时会从 UTF-8 转换为 IRIS 字符串,这可能会产生宽字符。
  • Python 字节对象作为 8 位字符串返回给 ObjectScript。如果字节对象的长度超过最大字符串长度,则返回 Python 字节对象。
  • 要将字节对象从 ObjectScript 传递到 Python,请使用 ##class(%SYS.Python).Bytes() 方法,该方法不会将基础 IRIS 字符串转换为 UTF-8

以下示例将 IRIS 字符串转换为字节类型的 Python 对象:

USER>set b = ##class(%SYS.Python).Bytes("Hello Bytes!")
 
USER>zwrite b
b=8@%SYS.Python  ; b'Hello Bytes!'  ; <OREF>
 
USER>zwrite builtins.type(b)
4@%SYS.Python  ; <class 'bytes'>  ; <OREF>

要在 IRIS 中构造大于 3.8MB 最大字符串长度的 Python 字节对象,可以使用 bytearray 对象并使用 extend() 方法附加更小的字节块。最后,将 bytearray 对象传递给内置的 bytes() 方法以获取字节表示:

USER>set ba = builtins.bytearray()
 
USER>do ba.extend(##class(%SYS.Python).Bytes("chunk 1"))
 
USER>do ba.extend(##class(%SYS.Python).Bytes("chunk 2"))
 
USER>zwrite builtins.bytes(ba)
"chunk 1chunk 2"

标准输出和标准错误映射

当使用嵌入式 Python 时,标准输出被映射到 IRIS 控制台,这意味着任何 print() 语句的输出都被发送到终端。标准错误映射到位于目录 <install-dir>/mgr 中的 IRIS messages.log 文件。

例如,考虑这个 Python 方法:

def divide(a, b):
    try:
        print(a/b)
    except ZeroDivisionError:
        print("Cannot divide by zero")
    except TypeError:
        import sys
        print("Bad argument type", file=sys.stderr)
    except:
        print("Something else went wrong")

如果在终端中测试此方法,可能会看到以下内容:

USER>set obj = ##class(%SYS.Python).Import("mymodule")
 
USER>do obj.divide(5, 0)
Cannot divide by zero
 
USER>do obj.divide(5, "hello")

如果除以零,则错误消息将定向到终端,但如果尝试除以字符串,则消息将发送到 messages.log

11/19/21-15:49:33:248 (28804) 0 [Python] Bad argument type

只有重要的消息应该发送到messages.log,以避免文件混乱。

在互操作性产品中使用嵌入式 Python

如果正在为 IRIS 中的互操作性产品编写自定义业务主机类或适配器类,则任何回调方法都必须用 ObjectScript 编写。回调方法是一种继承方法,默认情况下什么都不做,但设计为由用户实现。但是,回调方法中的 ObjectScript 代码可以使用 Python 库或调用 Python 中实现的其他方法。

以下示例显示了一个业务操作,该操作从传入消息中获取字符串值,并使用 Amazon Web Services (AWS) boto3 Python 库通过 Amazon Simple Notification Service (SNS) 以文本消息的形式将该字符串发送到手机。此 AWS 库的范围超出了本次讨论的范围,但可以在示例中看到 OnInit()OnMessage() 回调方法是用 ObjectScript 编写的,而方法 PyInit()SendSMS() 是用 ObjectScript 编写的Python

/// Send SMS via AWS SNS
Class dc.opcua.SMS Extends Ens.BusinessOperation
{

Parameter INVOCATION = "Queue";

/// AWS boto3 client
Property client As %SYS.Python;

/// json.dumps reference
Property tojson As %SYS.Python;

/// Phone number to send SMS to
Property phone As %String [ Required ];

Parameter SETTINGS = "phone:SMS";

Method OnMessage(request As Ens.StringContainer, Output response As Ens.StringContainer) As %Status
{
   #dim sc As %Status = $$$OK
   try {
      set response = ##class(Ens.StringContainer).%New(..SendSMS(request.StringValue))
      set code = +{}.%FromJSON(response.StringValue).ResponseMetadata.HTTPStatusCode
      set:(code'=200) sc = $$$ERROR($$$GeneralError, $$$FormatText("Error sending SMS,
         code: %1 (expected 200), text: %2", code, response.StringValue))
   } catch ex {
      set sc  = ex.AsStatus()
   }
   
   return sc
}

Method SendSMS(msg As %String) [ Language = python ]
{
   response = self.client.publish(PhoneNumber=self.phone, Message=msg)
   return self.tojson(response)
}

Method OnInit() As %Status
{
   #dim sc As %Status = $$$OK
   try {
      do ..PyInit()
   } catch ex {
      set sc = ex.AsStatus()
   }
   quit sc
}

/// Connect to AWS
Method PyInit() [ Language = python ]
{
   import boto3
   from json import dumps
   self.client = boto3.client("sns")
   self.tojson = dumps
}

}

注意:上面的 OnMessage() 方法中的代码包含一个额外的换行符,以便在打印此文档时更好地格式化。

此规则的一个例外是,如果它不使用来自适配器的输入,可以在 Python 中实现回调方法。

以下业务服务示例称为轮询器。在这种情况下,可以将业务服务设置为间隔运行并生成一个请求(在这种情况下包含一个随机字符串值),该请求将发送到业务流程进行处理。在此示例中,可以在 Python 中实现 OnProcessInput() 回调方法,因为它不使用方法签名中的 pInput 参数。

Class Debug.Service.Poller Extends Ens.BusinessService
{

Property Target As Ens.DataType.ConfigName;

Parameter SETTINGS = "Target:Basic";

Parameter ADAPTER = "Ens.InboundAdapter";

Method OnProcessInput(pInput As %RegisteredObject, Output pOutput As %RegisteredObject, 
    ByRef pHint As %String) As %Status [ Language = python ]
{
    import iris
    import random
    fruits = ["apple", "banana", "cherry"]
    fruit = random.choice(fruits)
    request = iris.cls('Ens.StringRequest')._New()
    request.StringValue = fruit + ' ' + iris.cls('Debug.Service.Poller').GetSomeText()
    return self.SendRequestAsync(self.Target,request)
}

ClassMethod GetSomeText() As %String
{
    Quit "is something to eat"
}

}
0
0 90
文章 姚 鑫 · 七月 17, 2022 4m read

第八章 使用嵌入式 Python (五)

通过引用传递参数

ObjectScript 编写的方法中的参数可以通过值或引用传递。在下面的方法中,签名中第二个和第三个参数前面的 ByRef 关键字表示它们打算通过引用传递。

ClassMethod SandwichSwitch(bread As %String, ByRef filling1 As %String, ByRef filling2 As %String)
{
    set bread = "whole wheat"
    set filling1 = "almond butter"
    set filling2 = "cherry preserves"
}

ObjectScript 调用方法时,在参数前放置一个句点以通过引用传递它,如下所示:

USER>set arg1 = "white bread"
 
USER>set arg2 = "peanut butter"
 
USER>set arg3 = "grape jelly"
 
USER>do ##class(User.EmbeddedPython).SandwichSwitch(arg1, .arg2, .arg3)
 
USER>write arg1
white bread
USER>write arg2
almond butter
USER>write arg3
cherry preserves

从输出中可以看出,调用 SandwichSwitch() 后变量 arg1 的值保持不变,而变量 arg2arg3 的值发生了变化。

由于 Python 本身不支持按引用调用,因此需要使用 iris.ref() 方法创建一个引用,以将每个要按引用传递的参数传递给该方法:

>>> import iris
>>> arg1 = "white bread"
>>> arg2 = iris.ref("peanut butter")
>>> arg3 = iris.ref("grape jelly")
>>> iris.cls('User.EmbeddedPython').SandwichSwitch(arg1, arg2, arg3)
>>> arg1
'white bread'
>>> arg2.value
'almond butter'
>>> arg3.value
'cherry preserves'

可以使用 value 属性访问 arg2arg3 的值,并查看它们在调用该方法后发生了变化。

Passing Values for True, False, and None

%SYS.Python 类具有 True()False()None() 方法,它们分别表示 Python 标识符 TrueFalseNone

例如:

USER>zwrite ##class(%SYS.Python).True()
2@%SYS.Python  ; True  ; <OREF>

如果需要将 TrueFalseNone 传递给 Python 方法,这些方法很有用。以下示例使用关键字或命名参数中显示的方法。

USER>do obj.mymethod(##class(%SYS.Python).True(), ##class(%SYS.Python).False(), ##class(%SYS.Python).None())
foo=True, bar=False, baz=None

如果将未命名的参数传递给需要关键字参数的 Python 方法,Python 会按照传入的顺序处理它们。

请注意,在检查 Python 方法返回给 ObjectScript 的值时,不需要使用方法 True()False()None()

假设Python模块mymodule也有一个方法isgreaterthan(),定义如下:

def isgreaterthan(a, b):
    return a > b

Python 中运行时,可以看到如果参数 a 大于 b,则该方法返回 True,否则返回 False

>>> mymodule.isgreaterthan(5, 4)
True

但是,当从 ObjectScript 调用时,返回值为 1,而不是 Python 标识符 True

USER>zwrite obj.isgreaterthan(5, 4)
1

Dictionaries

Python 中,字典通常用于以键/值对的形式存储数据,例如:

>>> mycar = {
...     "make": "Toyota",
...     "model": "RAV4",
...     "color": "blue"
... }
>>> print(mycar)
{'make': 'Toyota', 'model': 'RAV4', 'color': 'blue'}
>>> print(mycar["color"])
blue

ObjectScript 方面,可以使用 Python 内置模块的 dict() 方法来操作 Python 字典:

USER>set mycar = ##class(%SYS.Python).Builtins().dict()
 
USER>do mycar.setdefault("make", "Toyota")
 
USER>do mycar.setdefault("model", "RAV4")
 
USER>do mycar.setdefault("color", "blue")
 
USER>zwrite mycar
mycar=2@%SYS.Python  ; {'make': 'Toyota', 'model': 'RAV4', 'color': 'blue'}  ; <OREF>
 
USER>write mycar."__getitem__"("color")
blue

上面的示例使用字典方法 setdefault() 来设置键的值,并使用 __getitem__() 来获取键的值。

Lists

Python 中,列表存储值的集合,但没有键。列表中的项目通过其索引访问。

>>> fruits = ["apple", "banana", "cherry"]
>>> print(fruits)
['apple', 'banana', 'cherry']
>>> print(fruits[0])
apple

ObjectScript 中,可以使用 Python 内置模块的 list() 方法处理 Python 列表:

USER>set l = ##class(%SYS.Python).Builtins().list()
 
USER>do l.append("apple")
 
USER>do l.append("banana")
 
USER>do l.append("cherry")
 
USER>zwrite l
l=13@%SYS.Python  ; ['apple', 'banana', 'cherry']  ; <OREF>
 
USER>write l."__getitem__"(0)
apple

上面的示例使用列表方法 append() 将项目附加到列表中,并使用 __getitem__() 获取给定索引处的值。 (Python 列表是从零开始的。)

0
0 116
文章 姚 鑫 · 七月 16, 2022 4m read

第七章 使用嵌入式 Python (四)

弥合 ObjectScript 和嵌入式 Python 之间的差距

由于 ObjectScriptPython 语言之间的差异,将需要了解一些有助于弥合语言之间差距的信息。

ObjectScript 方面,%SYS.Python 类允许从 ObjectScript 使用 Python

Python 方面,iris 模块允许使用 Python 中的 ObjectScript。在 Python 中,键入 help(iris) 以获取其方法和函数的列表。

使用 Python 内置函数

builtins 包在 Python 解释器启动时自动加载,它包含语言的所有内置标识符,例如基对象类和所有内置数据类型类、异常类、函数和常量。

可以将此包导入 ObjectScript 以访问所有这些标识符,如下所示:

set builtins = ##class(%SYS.Python).Import("builtins")

Python print() 函数实际上是内置模块的一个方法,因此现在可以在 ObjectScript 中使用此函数:

USER>do builtins.print("hello world!")
hello world!

然后可以使用 zwrite 命令检查内置对象,因为它是一个 Python 对象,所以它使用内置包的 str() 方法来获取该对象的字符串表示形式。例如:

USER>zwrite builtins
builtins=5@%SYS.Python  ; <module 'builtins' (built-in)>  ; <OREF>

出于同样的原因,可以使用 builtins.list() 方法创建 Python 列表。下面的示例创建一个空列表:

USER>set list = builtins.list()
 
USER>zwrite list
list=5@%SYS.Python  ; []  ; <OREF>

可以使用 builtins.type() 方法查看变量列表是什么 Python 类型:

USER>zwrite builtins.type(list)
3@%SYS.Python  ; <class 'list'>  ; <OREF>

有趣的是,list() 方法实际上返回了一个 Python 类对象的实例,它代表一个列表。可以使用列表对象上的 dir() 方法查看列表类具有哪些方法:

USER>zwrite builtins.dir(list)
3@%SYS.Python  ; ['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', 
'__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', 
'__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__',  
'__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__','__repr__', '__reversed__',  
'__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append','clear', 
'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']  ; <OREF>
 

同样,可以使用 help() 方法获取有关列表对象的帮助。

USER>do builtins.help(list)
Help on list object:
class list(object)
 |  list(iterable=(), /)
 |
 |  Built-in mutable sequence.
 |
 |  If no argument is given, the constructor creates a new empty list.
 |  The argument must be an iterable if specified.
 |
 |  Methods defined here:
 |
 |  __add__(self, value, /)
 |      Return self+value.
 |
 |  __contains__(self, key, /)
 |      Return key in self.
 |
 |  __delitem__(self, key, /)
 |      Delete self[key].
.
.
.

注意:可以调用 %SYS.Python 类的 Builtins() 方法,而不是将 builtins 模块导入 ObjectScript

标识符名称

ObjectScriptPython 之间命名标识符的规则是不同的。例如,Python 方法名称中允许使用下划线 (_),实际上它被广泛用于所谓的“dunder”方法和属性(“dunder”是“双下划线”的缩写),例如 __getitem__ __class__ .要使用 ObjectScript 中的此类标识符,请将它们括在双引号中:

USER>set mylist = builtins.list()
 
USER>zwrite mylist."__class__"
2@%SYS.Python  ; <class list>  ; <OREF>

相反,IRIS 方法通常以百分号 (%) 开头。例如 %New()%Save()。要使用 Python 中的此类标识符,请将百分号替换为下划线。如果您有一个持久类 User.Person,以下 Python 代码行将创建一个新的 Person 对象。

>>> import iris
>>> p = iris.cls('User.Person')._New()

关键字或命名参数

Python 中的一个常见做法是在定义方法时使用关键字参数(也称为“命名参数”)。这使得在不需要时删除参数或根据名称而不是位置指定参数变得容易。例如,采用以下简单的 Python 方法:

def mymethod(foo=1, bar=2, baz="three"):
    print(f"foo={foo}, bar={bar}, baz={baz}")

由于 IRIS 没有关键字参数的概念,需要创建一个动态对象来保存关键字/值对,例如:

set args={ "bar": 123, "foo": "foo"}

如果 mymethod() 方法位于名为 mymodule.py 的模块中,则可以将其导入 ObjectScript 中,然后调用它,如下所示:

USER>set obj = ##class(%SYS.Python).Import("mymodule")
 
USER>set args={ "bar": 123, "foo": "foo"}
 
USER>do obj.mymethod(args...)
foo=foo, bar=123, baz=three

由于 baz 没有传入该方法,因此默认为它分配了“三”的值。

0
0 137