Usage¶
PyJulia provides a high-level interface which assumes a “normal” setup
(e.g., julia program is in your PATH) and a low-level interface
which can be used in a customized setup.
High-level interface¶
To call a Julia function in a Julia module, import the Julia module (say
Base) with:
>>> from julia import Base
and then call Julia functions in Base from python, e.g.,
>>> Base.sind(90)
Other variants of Python import syntax also work:
>>> import julia.Base
>>> from julia.Base import Enums # import a submodule
>>> from julia.Base import sin, sind # import functions from a module
The global namespace of Julia’s interpreter can be accessed via a
special module julia.Main:
>>> from julia import Main
You can set names in this module to send Python values to Julia:
>>> Main.xs = [1, 2, 3]
which allows it to be accessed directly from Julia code, e.g., it can be evaluated at Julia side using Julia syntax:
>>> Main.eval("sin.(xs)")
Low-level interface¶
If you need a custom setup for PyJulia, it must be done before
importing any Julia modules. For example, to use the Julia executable
named custom_julia, run:
>>> from julia import Julia
>>> jl = Julia(runtime="custom_julia")
You can then use, e.g.,
>>> from julia import Base
See also the API documentation for Julia.
IPython magic¶
In IPython (and therefore in Jupyter), you can directly execute Julia
code using %julia magic:
In [1]: %load_ext julia.magic
Initializing Julia runtime. This may take some time...
In [2]: %julia [1 2; 3 4] .+ 1
Out[2]:
array([[2, 3],
[4, 5]], dtype=int64)
You can call Python code from inside of %julia blocks via $var
for accessing single variables or py"..." for more complex
expressions:
In [3]: arr = [1, 2, 3]
In [4]: %julia $arr .+ 1
Out[4]:
array([2, 3, 4], dtype=int64)
In [5]: %julia sum(py"[x**2 for x in arr]")
Out[5]: 14
Inside of strings and quote blocks, $var and py"..." don’t call
Python and instead retain their usual Julia behavior. To call Python
code in these cases, you can “escape” one extra time:
In [6]: foo = "Python"
%julia foo = "Julia"
%julia ("this is $foo", "this is $($foo)")
Out[6]: ('this is Julia', 'this is Python')
Expressions in macro arguments also always retain the Julia behavior:
In [7]: %julia @eval $foo
Out[7]: 'Julia'
Results are automatically converted between equivalent Python/Julia
types (should they exist). You can turn this off by appending o to
the Python string:
In [8]: %julia typeof(py"1"), typeof(py"1"o)
Out[8]: (<PyCall.jlwrap Int64>, <PyCall.jlwrap PyObject>)
Code inside %julia blocks obeys the Python scope:
In [9]: x = "global"
...: def f():
...: x = "local"
...: ret = %julia py"x"
...: return ret
...: f()
Out[9]: 'local'
IPython configuration¶
PyJulia-IPython integration can be configured via IPython’s
configuration system. For the non-default behaviors, add the following
lines in, e.g., ~/.ipython/profile_default/ipython_config.py (see
Introduction to IPython
configuration).
To disable code completion in %julia and %%julia magics, use
c.JuliaMagics.completion = False # default: True
To disable code highlighting in %%julia magic for terminal
(non-Jupyter) IPython, use
c.JuliaMagics.highlight = False # default: True
To enable Revise.jl automatically, use
c.JuliaMagics.revise = True # default: False
Virtual environments¶
PyJulia can be used in Python virtual environments created by
virtualenv, venv, and any tools wrapping them such as
pipenv, provided that Python executable used in such environments
are linked to identical libpython used by PyCall. If this is not the
case, initializing PyJulia (e.g., import julia.Main) prints an
informative error message with detected paths to libpython. See PyCall
documentation for how to
configure Python executable.
Note that Python environment created by conda is not supported.