perfectlysoft/perfect-python
This project provides an expressway to import Python 2.7 module as a Server Side Swift Library.
Acknowledgement
A few updates were suggested by Chris Lattner. Thanks, @Chris.
Linux Build Note
Please make sure libpython2.7-dev was installed on Ubuntu 16.04:
$ sudo apt-get install libpython2.7-devMacOS Build Note
Please make sure Xcode 9.0 or later version was installed.
Quick Start
Add PerfectPython dependency to your 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"]),Then import two different libraries into the swift source code:
import PythonAPI
import PerfectPythonBefore any python api calls, make sure to initialize the library by calling Py_Initialize() function:
Py_Initialize()Import Python Modules
Use PyObj class to import python modules. In the following example, a python script /tmp/clstest.py has been imported into the current Swift context:
let pymod = try PyObj(path: "/tmp", import: "clstest")Access Python Variables
Once imported modules, you can use PyObj.load() function to access a variable value, or using PyObj.save() to store a new value to the current python variable.
For example, if there is a variable called stringVar in a python script:
stringVar = 'Hello, world'Then you can read its value in such a form:
if let str = pymod.load("stringVar")?.value as? String {
print(str)
// will print it out as "Hello, world!"
}You can also directly overwrite the value of the same variable:
try pymod.save("stringVar", newValue: "Hola, 🇨🇳🇨🇦!")NOTE Currently, Perfect-Python supports the following data types between Swift and Python:
Python Type|Swift Type|Remark ----------|---------|------- int|Int| float|Double| str|String| list|[Any]|Recursively dict|[String:Any]|Recursively
For example, you can convert a Swift String to PyObj by: let pystr = "Hello".python() or let pystr = try PyObj(value:"Hello").
To convert a PyObj to a Swift data type, e.g., a String, there are also two available approaches: let str = pystr.value as? String and let str = String(python: pystr).
Call A Python Function
Method PyObj.call() is available to execute function call with arguments. Consider the python code below:
def mymul(num1, num2):
return num1 * num2Perfect-Python can wrap this call by its name as a string and the arguments as an array:
if let res = pymod.call("mymul", args: [2,3])?.value as? Int {
print(res)
// the result will be 6
}Python Object Classes
The same PyObj.load() function helps to access the python class type, however, a following method PyObj.construct() should be called for object instance initialization. This method also supports parameters as an array for python object class construction.
Assume that there is a typical python class called Person, which has two properties name and age, and an object method called 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)To initialize such a class object in Swift, the first two steps look like:
if let personClass = pymod.load("Person"),
let person = personClass.construct(["rocky", 24]) {
// person is now the object instance
}Then you can access the properties and class methods as common variables and functions do:
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)
}Callbacks
Consider the following python code as you can execute a function as a parameter like x = caller('Hello', callback):
def callback(msg):
return 'callback: ' + msg
def caller(info, func):
return func(info)The equivalent Swift code is nothing special but using the objective callback function as an argument before calling:
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"
}Further Information
For more information on the Perfect project, please visit perfect.org.
Now WeChat Subscription is Available (Chinese)
<p align=center><img src="https://raw.githubusercontent.com/PerfectExamples/Perfect-Cloudinary-ImageUploader-Demo/master/qr.png"></p>
Package Metadata
Repository: perfectlysoft/perfect-python
Default branch: master
README: README.md