本项目提供了一种将 Python 2.7 模块导入为服务器端 Swift 库的快速通道。
此软件包使用 Swift Package Manager 构建,是 Perfect 项目的一部分,但也可以独立运行。
请确保您已安装并激活最新的 Swift 4.1.2 工具链。
Chris Lattner 提出了一些更新建议。 感谢 @Chris。
请确保在 Ubuntu 16.04 上安装了 libpython2.7-dev。
$ sudo apt-get install libpython2.7-dev
请确保已安装 Xcode 9.0 或更高版本。
将 PerfectPython 依赖项添加到您的 Package.swift 文件中。
.package(url: "https://github.com/PerfectlySoft/Perfect-Python.git",
from: "3.2.0")
// on target section:
.target(
// name: "your project name",
dependencies: ["PerfectPython"]),
然后将两个不同的库导入到 Swift 源代码中。
import PythonAPI
import PerfectPython
在任何 Python API 调用之前,请务必通过调用 Py_Initialize()
函数来初始化库。
Py_Initialize()
使用 PyObj
类来导入 Python 模块。 在以下示例中,Python 脚本 /tmp/clstest.py
已被导入到当前的 Swift 上下文中。
let pymod = try PyObj(path: "/tmp", import: "clstest")
导入模块后,您可以使用 PyObj.load()
函数来访问变量值,或者使用 PyObj.save()
将新值存储到当前的 Python 变量中。
例如,如果 Python 脚本中有一个名为 stringVar
的变量。
stringVar = 'Hello, world'
那么您可以按照以下形式读取它的值。
if let str = pymod.load("stringVar")?.value as? String {
print(str)
// will print it out as "Hello, world!"
}
您也可以直接覆盖同一变量的值。
try pymod.save("stringVar", newValue: "Hola, 🇨🇳🇨🇦!")
注意 目前,Perfect-Python 支持 Swift 和 Python 之间的以下数据类型。
Python 类型 | Swift 类型 | 备注 |
---|---|---|
int | Int | |
float | Double | |
str | String | |
list | [Any] | 递归地 |
dict | [String:Any] | 递归地 |
例如,您可以通过以下方式将 Swift String
转换为 PyObj
:let pystr = "Hello".python()
或 let pystr = try PyObj(value:"Hello")
。
要将 PyObj
转换为 Swift 数据类型(例如 String
),也有两种方法可用:let str = pystr.value as? String
和 let str = String(python: pystr)
。
PyObj.call()
方法可用于执行带有参数的函数调用。 考虑下面的 Python 代码。
def mymul(num1, num2):
return num1 * num2
Perfect-Python 可以通过其名称(作为字符串)和参数(作为数组)来封装此调用。
if let res = pymod.call("mymul", args: [2,3])?.value as? Int {
print(res)
// the result will be 6
}
相同的 PyObj.load()
函数有助于访问 Python 类类型,但是,应该调用以下方法 PyObj.construct()
来进行对象实例初始化。 此方法还支持参数作为 Python 对象类构造的数组。
假设有一个典型的 Python 类,名为 Person
,它具有两个属性 name
和 age
,以及一个对象方法,名为 intro()
。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def intro(self):
return 'Name: ' + self.name + ', Age: ' + str(self.age)
要在 Swift 中初始化这样的类对象,前两个步骤如下所示。
if let personClass = pymod.load("Person"),
let person = personClass.construct(["rocky", 24]) {
// person is now the object instance
}
然后,您可以像访问普通变量和函数一样访问属性和类方法。
if let name = person.load("name")?.value as? String,
let age = person.load("age")?.value as? Int,
let intro = person.call("intro", args: [])?.value as? String {
print(name, age, intro)
}
考虑以下 Python 代码,您可以将函数作为参数执行,例如 x = caller('Hello', callback)
。
def callback(msg):
return 'callback: ' + msg
def caller(info, func):
return func(info)
等效的 Swift 代码没有什么特别之处,只是在使用前,将目标回调函数用作参数。
if let fun = pymod.load("callback"),
let result = pymod.call("caller", args: ["Hello", fun]),
let v = result.value as? String {
print(v)
// it will be "callback: Hello"
}
有关 Perfect 项目的更多信息,请访问 perfect.org。