你没看错:Swift可以直接调用Python函数库
上周Perfect又推出了新一轮服务器端Swift增强函数库:Perfect-Python。对,你没看错,在服务器端Swift 其实可以轻松从其他语种的函数库中直接拿来调用,不需要修改任何内容。如果没有类似经验的童鞋可以参考拙作: 而Perfect-Python不是简单嵌入源代码的问题,是允许用户直接调用Python函数库本身!!!! 为什么花大力气做这些东西?很简单,程序员都是很懒的家伙,与其重新把几万行代码重写一遍,不如直接抓壮丁来的快——现成成熟的代码在快速原型法中起的作用之大难以想象。 不错,是由一些很矫情的家伙宣称什么“语言的纯洁性”,比如Vapor,去年一直号称要“纯洁的Swift”,结果两周前终于顶不住压力,参考上一期Ryan的报告可以看到:
看见了吗?Vapor作为典型的反面教材,在陷入服务器性能问题的泥潭后终于招架不住投降了——用了两年时间证明一个光鲜的口号是错误的,这是什么样的代价!“实践是检验真理的唯一标准”——闭门思过去吧。 实践证明,全栈开发需要扬长避短,然后用统一的一种编译型语言做主调是在性能和效率上达到最合理平衡点的,目的是:
好了,言归正传,我们看一下Perfect-Python的具体用法: 本项目提供了在Swift服务器应用上直接引用Python 2.7函数库的简便方法。 本项目采用Swift Package Manager 软件包管理器编译,是Perfect 项目的一部分,但是也可以独立运行 在使用之前请准备好最新的Swift 3.1 / 4.0 工具链 Linux 编译事项首先请确保 libpython2.7-dev 已经在 Ubuntu 16.04 上正确安装: $ sudo apt-get install libpython2.7-dev MacOS 编译事项请确定 Xcode 8.3.3 / 9.0 以上版本已经正确安装 快速上手首先在Package.swift中增加依存关系: .Package(url: "https://github.com/PerfectlySoft/Perfect-Python.git",majorVersion: 1) 然后将下列头文件导入Swift源代码: import PythonAPI import PerfectPython 请注意在任何程序调用之前,必须调用 Py_Initialize() 导入Python函数库模块使用 let pymod = try PyObj(path: "/tmp",import: "clstest") 访问Python变量导入模块后,您可以使用 比如,以下python脚本中有个叫做 stringVar = 'Hello,world' 那么要取得这个字符串的值只需要这样做: if let str = pymod.load("stringVar")?.value as? String { print(str) // 会打印变量的字符串值 "Hello,world!" } 此时您还可以为该变量直接写入新的字符串值: try pymod.save("stringVar",newValue: "Hola!") 注意 目前,Perfect-Python仅支持如下Swift / Python数据类型自动转换:
比如,您可以把一个字符串 反过来,如果要把 执行Python函数方法 def mymul(num1,num2): return num1 * num2 Perfect-Python 可以用下列方法封装并调用以上函数,您所需要注意的仅仅是其函数名称以及参数。其中函数名称用字符串代替,而参数用一个数组表达: if let res = pymod.call("mymul",args: [2,3])?.value as? Int { print(res) // 结果为 6 } Python类对象请同样使用 假设如下脚本的典型python类对象 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代码,此时如果执行 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) // 结果是 "callback: Hello" } 更多信息关于本项目更多内容,请参考perfect.org. 扫一扫 Perfect 官网微信号
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |