Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cjdoris/pyrun.jl
Reliable Python-Julia interop
https://github.com/cjdoris/pyrun.jl
Last synced: 24 days ago
JSON representation
Reliable Python-Julia interop
- Host: GitHub
- URL: https://github.com/cjdoris/pyrun.jl
- Owner: cjdoris
- License: mit
- Created: 2022-07-31T00:44:19.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-11-26T12:18:17.000Z (12 months ago)
- Last Synced: 2023-11-26T14:32:28.635Z (12 months ago)
- Language: Python
- Size: 23.4 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# PyRun.jl
Another Python-Julia interoperability package. It's a simple as:
```julia
using PyRun
pyrun("print('Hello from Python!')")
```This differs from `PythonCall` and `PyCall` in that those packages embed the Python
interpreter into the current process, whereas `PyRun` launches a new Python process and
communicates with that.Advantages of this approach are:
- Library mismatches do not occur, such as when Julia and Python require different versions
of LLVM.
- Other implementations of Python can be used, such as PyPy.
- Python's multithreading and multiprocessing works without issue.
- Asynchronous Julia and Python code both work and can be mixed.
- You can easily use multiple Python processes - construct more with `PyProcess()` and pass
them as the first argument to `pyrun`.Disadvantages are:
- Inter-process communication is slow (rougly 200μs per run), so you should not write tight
loops in Julia which call Python.
- No shared memory, since Python is running in a separate process. (But you could use
something like Apache Arrow.)## Install
```
pkg> add https://github.com/cjdoris/PyRun.jl
```## Usage
```julia
pyrun([p::PyProcess], code; scope, locals)
```Run the given piece of Python `code`.
If the process is not specified, a global default process is used.
The scope defines the module in which the code is run. It may be of the form "@name" to
create a new module in a separate namespace.The locals is a named tuple or dict defining the locals when running the code. May also be
`nothing` to run the code in global scope.The module `jl` is available to the code. You may call `jl.ret(x)` to return `x` from the
code. You can control the returned format with `jl.ret(x, fmt)` - see the examples below.## Examples
A simple print statement:
```julia
julia> pyrun("print('hello world!')")
hello world!
```Say hello the given user:
```julia
julia> pyrun("print('hello', name)", locals=(name="alice",))
hello alice
```Do some arithmetic and return the answer (converted automatically to Int):
```julia
julia> pyrun("jl.ret(x + y)", locals=(x=1, y=2))
3
```Make and return a Python list (converted automatically to a vector):
```julia
julia> pyrun("jl.ret([1, 2, 3])")
3-element Vector{Int64}:
1
2
3
```Explicitly convert to a PyRef (supports attributes, indexing, calling, etc.):
```julia
julia> x = pyrun("jl.ret([1, 2, 3], 'ref')")
PyRef: [1, 2, 3]julia> length(x)
3julia> x[2]
PyRef: 3julia> x.append(4)
PyRef: Nonejulia> x
PyRef: [1, 2, 3, 4]
```