文章
姚 鑫 · 七月 16 阅读大约需 4 分钟

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

第七章 使用嵌入式 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 40
讨论 (0)1
登录或注册以继续