Calling Julia from Python for the real world.
Features:
-
Cross-platform support for both dynamically linked Python and statically linked Python.
-
Support Julia system images.
Prerequisites: Python (>=3.7), Julia (>=1.6)
Then install the tyjuliacall Python package and TyPython Julia package.
pip install -U tyjuliacall
julia -e "import Pkg; Pkg.add(\"TyPython\")"from tyjuliasetup import use_sysimage # CAUTIOUS: not 'tyjuliacall'!
use_sysimage(r"/path/to/sysimg")
# if your sysimage contains TyPython,
# you could call use_system_typython() to reduce the time cost of setting up julia.
from tyjuliacall import Base
print(
"current sysimage in use",
Base.unsafe_string(Base.JLOptions().image_file))
# out: /path/to/sysimg虽然tyjuliacall允许在Python和Julia之间传递任意数据,但由于是两门不同的语言,数据转换的类型对应关系是复杂的。
为了保证代码的后向兼容性,使得规范的代码在不同版本的Syslab/tyjuliacall上都可以运行,建议只使用如下的数据类型转换。
Python向Julia函数传参时,推荐只使用下表左边的数据类型,以保证代码的后向兼容。
| Python Type | Julia Type |
|---|---|
| 基本类型 | |
int |
Int64 |
float |
Float64 |
bool |
Bool |
complex |
ComplexF64 |
None |
nothing |
str |
String |
| 组合类型 | |
numpy.ndarray (dtype为数字或字符串或bool) |
原生Array |
tuple,且元素均为表中数据类型 |
Tuple |
对于Python传递给Julia的tuple,其各个元素按照以上规则依次转换。
TIPS: 如何传递bytearray或者bytes到Julia?
-
向Julia函数传递bytes时,可以改为传递一个uint8的数组。
无拷贝传参:
np.array(memoryview(b'mybytes'), dtype=np.uint8)拷贝传参:np.array(list(b'mybytes'), dtype=np.uint8) -
向Julia函数传递bytearray时,可以改为传递一个uint8的数组。
无拷贝传参:
np.asarray(bytearray(b'mybytes')))
当获取Julia函数返回值,或导入Julia模块的非函数对象时,将发生Julia到Python的数据传递。
保证后向兼容的Julia到Python数据转换关系如下表所示:
| Julia | Python |
|---|---|
| 基本类型 | |
Integer子类型 |
int |
AbstractFloat子类型 |
float |
Bool |
bool |
Complex子类型 |
complex |
nothing对象 |
None |
AbstractString子类型 |
str |
Vector{UInt8} |
bytearray |
| 组合类型 | |
AbstrctArray{T} (T见下方说明) |
numpy.ndarray |
Tuple{T1, ..., Tn}, 且Ti为该表中的类型 |
tuple |
| 其余Julia类型 | tyjuliacall.JV |
一个Julia AbstrctArray能转换为numpy数组,当且仅当其元素类型T是以下类型之一
Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64Float16, Float32, Float64ComplexF16, ComplexF32, ComplexF64Bool
注意,当类型为Vector{String}或者Array{String, 2}的Julia对象被返回给Python时,它被封装为一个tyjuliacall.JV类型。
- 不要对Julia包/模块使用
from ... import *。 Vector{String}传到Python是一个tyjuliacall.JV,这是一个纯Julia对象的包装,因此下标索引是从1开始的。