The Julia module PythonCall
Installation
This package is in the general registry, so to install just type ]
in the Julia REPL and run:
pkg> add PythonCall
Getting started
Import the module with:
julia> using PythonCall
By default this will initialize a conda environment in your Julia environment, install Python into it, load the corresponding Python library and initialize an interpreter.
Now you can interact with Python as follows:
julia> re = pyimport("re")
Python module: <module 're' from '[...]/lib/re.py'>
julia> words = re.findall("[a-zA-Z]+", "PythonCall.jl is very useful!")
Python list: ['PythonCall', 'jl', 'is', 'very', 'useful']
julia> sentence = Py(" ").join(words)
Python str: 'PythonCall jl is very useful'
julia> pyconvert(String, sentence)
"PythonCall jl is very useful"
In this example:
- We used
pyimport
to import there
module. Equivalently we could have done@py import re
(see@py
). - We called its
findall
function on a pair of strings, which were automatically converted to Python strings (see Conversion to Python). - We called
Py
to explicitly convert a string to a Python string, so that we could call itsjoin
method. All Python objects are of typePy
. - We called
pyconvert
to convert the Python stringsentence
to a Julia string (see Conversion to Julia).
What to read next:
- The rest of this page details the functions for interacting with Python objects, of type
Py
. - If you need to install Python packages, read here.
- When you call a Python function, such as
re.findall(...)
in the above example, its arguments are converted to Python according to this table and its return value is aPy
. - Python objects can be converted to Julia objects using
pyconvert
with rules according to this table. - Python objects can also be wrapped to provide more Julian semantics. For example, a
PyDict
wraps a Python dict as a Julia dict, and aPyArray
wraps a Python array or buffer as a Julia array. See here.
Py
PythonCall.Py
— TypePy(x)
Convert x
to a Python object.
PythonCall.@pyconst
— Macro@pyconst ex
Equivalent to Py(ex)
but always returns the exact same Julia object.
That is, if foo() = @pyconst ex
then foo() === foo()
.
The expression ex
is evaluated the first time the code is run.
If ex
is a string literal, the string is interned.
Do not use this macro at the top level of a module. Instead, use pynew()
and pycopy!()
.
The object pybuiltins
has all the standard Python builtin objects as its properties. Hence you can access pybuiltins.None
and pybuiltins.TypeError
.
@py
PythonCall.@py
— Macro@py expr
Evaluate the given expression using Pythonic semantics.
For example:
f(x, y)
is translated topycall(f, x, y)
x + y
is translated topyadd(x, y)
x === y
is translated topyis(x, y)
x.foo
is translated topygetattr(x, "foo")
Compound statements such as begin
, if
, while
and for
are supported.
See the online documentation for more details.
Python functions
Most of the functions in this section are essentially Python builtins with a py
prefix. For example pyint(x)
converts x
to a Python int
and is equivalent to int(x)
in Python when x
is a Python object.
Notable exceptions are:
pyconvert
to convert a Python object to a Julia object.pyimport
to import a Python module.pyjl
to directly wrap a Julia object as a Python object.pyclass
to construct a new class.pywith
to emulate the Pythonwith
statement.
If a Julia value is passed as an argument to one of these functions, it is converted to a Python value using the rules documented here.
Constructors
These functions construct Python objects of builtin types from Julia values.
PythonCall.pybool
— Functionpybool(x)
Convert x
to a Python bool
.
PythonCall.pyint
— Functionpyint(x=0)
Convert x
to a Python int
.
PythonCall.pyfloat
— Functionpyfloat(x=0.0)
Convert x
to a Python float
.
PythonCall.pycomplex
— Functionpycomplex(x=0.0)
pycomplex(re, im)
Convert x
to a Python complex
, or create one from given real and imaginary parts.
PythonCall.pystr
— Functionpystr(x)
Convert x
to a Python str
.
PythonCall.pybytes
— Functionpybytes(x)
Convert x
to a Python bytes
.
PythonCall.pytuple
— Functionpytuple(x=())
Convert x
to a Python tuple
.
If x
is a Python object, this is equivalent to tuple(x)
in Python. Otherwise x
must be iterable.
PythonCall.pylist
— Functionpylist(x=())
Convert x
to a Python list
.
If x
is a Python object, this is equivalent to list(x)
in Python. Otherwise x
must be iterable.
PythonCall.pycollist
— Functionpycollist(x::AbstractArray)
Create a nested Python list
-of-list
s from the elements of x
. For matrices, this is a list of columns.
PythonCall.pyrowlist
— Functionpyrowlist(x::AbstractArray)
Create a nested Python list
-of-list
s from the elements of x
. For matrices, this is a list of rows.
PythonCall.pyset
— Functionpyset(x=())
Convert x
to a Python set
.
If x
is a Python object, this is equivalent to set(x)
in Python. Otherwise x
must be iterable.
PythonCall.pyfrozenset
— Functionpyfrozenset(x=())
Convert x
to a Python frozenset
.
If x
is a Python object, this is equivalent to frozenset(x)
in Python. Otherwise x
must be iterable.
PythonCall.pydict
— Functionpydict(x)
pydict(; x...)
Convert x
to a Python dict
. In the second form, the keys are strings.
If x
is a Python object, this is equivalent to dict(x)
in Python. Otherwise x
must iterate over key-value pairs.
PythonCall.pyslice
— Functionpyslice([start], stop, [step])
Construct a Python slice
. Unspecified arguments default to None
.
PythonCall.pyrange
— Functionpyrange([[start], [stop]], [step])
Construct a Python range
. Unspecified arguments default to None
.
PythonCall.pymethod
— Functionpymethod(x)
Convert callable x
to a Python instance method.
PythonCall.pytype
— Functionpytype(x)
The Python type
of x
.
PythonCall.pyclass
— Functionpyclass(name, bases=(); members...)
Construct a new Python type with the given name, bases and members.
Equivalent to pytype(name, bases, members)
.
Builtins
These functions mimic the Python builtin functions or keywords of the same name.
PythonCall.pyimport
— Functionpyimport(m)
pyimport(m => k)
pyimport(m => (k1, k2, ...))
pyimport(m1, m2, ...)
Import a module m
, or an attribute k
, or a tuple of attributes.
If several arguments are given, return the results of importing each one in a tuple.
PythonCall.pywith
— Functionpywith(f, o, d=nothing)
Equivalent to with o as x: f(x)
in Python, where x
is a Py
.
On success, the value of f(x)
is returned.
If an exception occurs but is suppressed then d
is returned.
PythonCall.pyis
— Functionpyis(x, y)
True if x
and y
are the same Python object. Equivalent to x is y
in Python.
PythonCall.pyrepr
— Functionpyrepr(x)
Equivalent to repr(x)
in Python.
PythonCall.pyascii
— Functionpyascii(x)
Equivalent to ascii(x)
in Python.
PythonCall.pyhasattr
— Functionpyhasattr(x, k)
Equivalent to hasattr(x, k)
in Python.
PythonCall.pygetattr
— Functionpygetattr(x, k, [d])
Equivalent to getattr(x, k)
or x.k
in Python.
If d
is specified, it is returned if the attribute does not exist.
PythonCall.pysetattr
— Functionpysetattr(x, k, v)
Equivalent to setattr(x, k, v)
or x.k = v
in Python.
PythonCall.pydelattr
— Functionpydelattr(x, k)
Equivalent to delattr(x, k)
or del x.k
in Python.
PythonCall.pydir
— Functionpydir(x)
Equivalent to dir(x)
in Python.
PythonCall.pycall
— Functionpycall(f, args...; kwargs...)
Call the Python object f
with the given arguments.
PythonCall.pylen
— Functionpylen(x)
The length of x
. Equivalent to len(x)
in Python, converted to an Integer
.
PythonCall.pycontains
— Functionpycontains(x, v)
Equivalent to v in x
in Python.
PythonCall.pyin
— Functionpyin(v, x)
Equivalent to v in x
in Python.
PythonCall.pygetitem
— Functionpygetitem(x, k)
Equivalent to getitem(x, k)
or x[k]
in Python.
PythonCall.pysetitem
— Functionpysetitem(x, k, v)
Equivalent to setitem(x, k, v)
or x[k] = v
in Python.
PythonCall.pydelitem
— Functionpydelitem(x, k)
Equivalent to delitem(x, k)
or del x[k]
in Python.
PythonCall.pyissubclass
— Functionpyissubclass(s, t)
Test if s
is a subclass of t
. Equivalent to issubclass(s, t)
in Python.
PythonCall.pyisinstance
— Functionpyisinstance(x, t)
Test if x
is of type t
. Equivalent to isinstance(x, t)
in Python.
PythonCall.pyhash
— Functionpyhash(x)
Equivalent to hash(x)
in Python, converted to an Integer
.
PythonCall.pyiter
— Functionpyiter(x)
Equivalent to iter(x)
in Python.
PythonCall.pynext
— Functionpynext(x)
Equivalent to next(x)
in Python.
PythonCall.pyhelp
— Functionpyhelp([x])
Equivalent to help(x)
in Python.
PythonCall.pyprint
— Functionpyprint(...)
Equivalent to print(...)
in Python.
PythonCall.pyall
— Functionpyall(x)
Equivalent to all(x)
in Python.
PythonCall.pyany
— Functionpyany(x)
Equivalent to any(x)
in Python.
PythonCall.pycallable
— Functionpycallable(x)
Equivalent to callable(x)
in Python.
PythonCall.pyeval
— Functionpyeval([T=Py], code, globals, locals=nothing)
Evaluate the given Python code
, returning the result as a T
.
If globals
is a Module
, then a persistent dict
unique to that module is used.
By default the code runs in global scope (i.e. locals===globals
). To use a temporary local scope, set locals
to ()
, or to a NamedTuple
of variables to include in the scope.
See also @pyeval
.
Examples
The following computes 1.1+2.2
in the Main
module as a Float64
:
pyeval(Float64, "x+y", Main, (x=1.1, y=2.2)) # returns 3.3
PythonCall.pyexec
— Functionpyexec([T=Nothing], code, globals, locals=nothing)
Execute the given Python code
.
If globals
is a Module
, then a persistent dict
unique to that module is used.
By default the code runs in global scope (i.e. locals===globals
). To use a temporary local scope, set locals
to ()
, or to a NamedTuple
of variables to include in the scope.
If T==Nothing
then returns nothing
. Otherwise T
must be a concrete NamedTuple
type and the corresponding items from locals
are extracted and returned.
See also @pyexec
.
Examples
The following computes 1.1+2.2
in the Main
module as a Float64
:
pyexec(@NamedTuple{ans::Float64}, "ans=x+y", Main, (x=1.1, y=2.2)) # returns (ans = 3.3,)
Marking variables as global
saves them into the module scope, so that they are available in subsequent invocations:
pyexec("global x; x=12", Main)
pyeval(Int, "x", Main) # returns 12
PythonCall.pycompile
— Functionpycompile(...)
Equivalent to compile(...)
in Python.
PythonCall.@pyeval
— Macro@pyeval [inputs =>] code [=> T]
Evaluate the given code
in a new local scope and return the answer as a T
.
The global scope is persistent and unique to the current module.
The code
must be a literal string or command.
The inputs
is a tuple of inputs of the form v=expr
to be included in the local scope. Only v
is required, expr
defaults to v
.
Examples
The following computes 1.1+2.2
and returns a Float64
:
@pyeval (x=1.1, y=2.2) => `x+y` => Float64 # returns 3.3
PythonCall.@pyexec
— Macro@pyexec [inputs =>] code [=> outputs]
Execute the given code
in a new local scope.
The global scope is persistent and unique to the current module.
The code
must be a literal string or command.
The inputs
is a tuple of inputs of the form v=expr
to be included in the local scope. Only v
is required, expr
defaults to v
.
The outputs
is a tuple of outputs of the form x::T=v
, meaning that v
is extracted from locals, converted to T
and assigned to x
. Only x
is required: T
defaults to Py
and v
defaults to x
.
Examples
The following computes 1.1+2.2
and assigns its value to ans
as a Float64
:
@pyexec (x=1.1, y=2.2) => `ans=x+y` => ans::Float64 # returns 3.3
Marking variables as global
saves them into the module scope, so that they are available in subsequent invocations:
@pyexec `global x; x=12`
@pyeval `x` => Int # returns 12
Conversion to Julia
These functions convert Python values to Julia values, using the rules documented here.
PythonCall.pyconvert
— Functionpyconvert(T, x, [d])
Convert the Python object x
to a T
.
If d
is specified, it is returned on failure instead of throwing an error.
PythonCall.@pyconvert
— Macro@pyconvert(T, x, [onfail])
Convert the Python object x
to a T
.
On failure, evaluates to onfail
, which defaults to return pyconvert_unconverted()
(mainly useful for writing conversion rules).
Wrap Julia values
These functions explicitly wrap Julia values into Python objects, documented here.
As documented here, Julia values are wrapped like this automatically on conversion to Python, unless the value is immutable and has a corresponding Python type.
PythonCall.pyjl
— Functionpyjl([t], x)
Create a Python object wrapping the Julia object x
.
If x
is mutable, then mutating the returned object also mutates x
, and vice versa.
Its Python type is normally inferred from the type of x
, but can be specified with t
.
For example if x
is an AbstractVector
then the object will have type juliacall.VectorValue
. This object will satisfy the Python sequence interface, so for example uses 0-up indexing.
PythonCall.pyjlraw
— Functionpyjlraw(v)
Create a Python object wrapping the Julia object x
.
It has type juliacall.RawValue
. This has a much more rigid "Julian" interface than pyjl(v)
. For example, accessing attributes or calling this object will always return a RawValue
.
PythonCall.pyisjl
— Functionpyisjl(x)
Test whether x
is a wrapped Julia value, namely an instance of juliacall.ValueBase
.
PythonCall.pyjlvalue
— Functionpyjlvalue(x)
Extract the value from the wrapped Julia value x
.
PythonCall.pytextio
— Functionpytextio(io::IO)
Wrap io
as a Python text IO object.
PythonCall.pybinaryio
— Functionpybinaryio(io::IO)
Wrap io
as a Python binary IO object.
This is the default behaviour of Py(io)
.
Arithmetic
These functions are equivalent to the corresponding Python arithmetic operators.
Note that the equivalent Julia operators are overloaded to call these when all arguments are Py
(or Number
). Hence the following are equivalent: Py(1)+Py(2)
, Py(1)+2
, pyadd(1, 2)
, pyadd(Py(1), Py(2))
, etc.
PythonCall.pyneg
— Functionpyneg(x)
Equivalent to -x
in Python.
PythonCall.pypos
— Functionpypos(x)
Equivalent to +x
in Python.
PythonCall.pyabs
— Functionpyabs(x)
Equivalent to abs(x)
in Python.
PythonCall.pyinv
— Functionpyinv(x)
Equivalent to ~x
in Python.
PythonCall.pyindex
— Functionpyindex(x)
Convert x
losslessly to an int
.
PythonCall.pyadd
— Functionpyadd(x, y)
Equivalent to x + y
in Python.
PythonCall.pysub
— Functionpysub(x, y)
Equivalent to x - y
in Python.
PythonCall.pymul
— Functionpymul(x, y)
Equivalent to x * y
in Python.
PythonCall.pymatmul
— Functionpymatmul(x, y)
Equivalent to x @ y
in Python.
PythonCall.pypow
— Functionpypow(x, y, z=None)
Equivalent to x ** y
or pow(x, y, z)
in Python.
PythonCall.pyfloordiv
— Functionpyfloordiv(x, y)
Equivalent to x // y
in Python.
PythonCall.pytruediv
— Functionpytruediv(x, y)
Equivalent to x / y
in Python.
PythonCall.pymod
— Functionpymod(x, y)
Equivalent to x % y
in Python.
PythonCall.pydivmod
— Functionpydivmod(x, y)
Equivalent to divmod(x, y)
in Python.
PythonCall.pylshift
— Functionpylshift(x, y)
Equivalent to x << y
in Python.
PythonCall.pyrshift
— Functionpyrshift(x, y)
Equivalent to x >> y
in Python.
PythonCall.pyand
— Functionpyand(x, y)
Equivalent to x & y
in Python.
PythonCall.pyxor
— Functionpyxor(x, y)
Equivalent to x ^ y
in Python.
PythonCall.pyor
— Functionpyor(x, y)
Equivalent to x | y
in Python.
PythonCall.pyiadd
— Functionpyiadd(x, y)
In-place add. x = pyiadd(x, y)
is equivalent to x += y
in Python.
PythonCall.pyisub
— Functionpyisub(x, y)
In-place subtract. x = pyisub(x, y)
is equivalent to x -= y
in Python.
PythonCall.pyimul
— Functionpyimul(x, y)
In-place multiply. x = pyimul(x, y)
is equivalent to x *= y
in Python.
PythonCall.pyimatmul
— Functionpyimatmul(x, y)
In-place matrix multiply. x = pyimatmul(x, y)
is equivalent to x @= y
in Python.
PythonCall.pyipow
— Functionpyipow(x, y, z=None)
In-place power. x = pyipow(x, y)
is equivalent to x **= y
in Python.
PythonCall.pyifloordiv
— Functionpyifloordiv(x, y)
In-place floor divide. x = pyifloordiv(x, y)
is equivalent to x //= y
in Python.
PythonCall.pyitruediv
— Functionpyitruediv(x, y)
In-place true division. x = pyitruediv(x, y)
is equivalent to x /= y
in Python.
PythonCall.pyimod
— Functionpyimod(x, y)
In-place subtraction. x = pyimod(x, y)
is equivalent to x %= y
in Python.
PythonCall.pyilshift
— Functionpyilshift(x, y)
In-place left shift. x = pyilshift(x, y)
is equivalent to x <<= y
in Python.
PythonCall.pyirshift
— Functionpyirshift(x, y)
In-place right shift. x = pyirshift(x, y)
is equivalent to x >>= y
in Python.
PythonCall.pyiand
— Functionpyiand(x, y)
In-place and. x = pyiand(x, y)
is equivalent to x &= y
in Python.
PythonCall.pyixor
— Functionpyixor(x, y)
In-place xor. x = pyixor(x, y)
is equivalent to x ^= y
in Python.
PythonCall.pyior
— Functionpyior(x, y)
In-place or. x = pyior(x, y)
is equivalent to x |= y
in Python.
Logic
These functions are equivalent to the corresponding Python logical operators.
Note that the equivalent Julia operators are overloaded to call these when all arguments are Py
(or Number
). Hence the following are equivalent: Py(1) < Py(2)
, Py(1) < 2
, pylt(1, 2)
, pylt(Py(1), Py(2))
, etc.
Note that the binary operators by default return Py
(not Bool
) since comparisons in Python do not necessarily return bool
.
PythonCall.pytruth
— Functionpytruth(x)
The truthyness of x
. Equivalent to bool(x)
in Python, converted to a Bool
.
PythonCall.pynot
— Functionpynot(x)
The falsyness of x
. Equivalent to not x
in Python, converted to a Bool
.
PythonCall.pyeq
— Functionpyeq(x, y)
pyeq(Bool, x, y)
Equivalent to x == y
in Python. The second form converts to Bool
.
PythonCall.pyne
— Functionpyne(x, y)
pyne(Bool, x, y)
Equivalent to x != y
in Python. The second form converts to Bool
.
PythonCall.pyle
— Functionpyle(x, y)
pyle(Bool, x, y)
Equivalent to x <= y
in Python. The second form converts to Bool
.
PythonCall.pylt
— Functionpylt(x, y)
pylt(Bool, x, y)
Equivalent to x < y
in Python. The second form converts to Bool
.
PythonCall.pyge
— Functionpyge(x, y)
pyge(Bool, x, y)
Equivalent to x >= y
in Python. The second form converts to Bool
.
PythonCall.pygt
— Functionpygt(x, y)
pygt(Bool, x, y)
Equivalent to x > y
in Python. The second form converts to Bool
.
Installing Python packages
PythonCall uses CondaPkg.jl to manage its dependencies. Namely, CondaPkg will automatically install Python and any packages required into a Conda environment specific to your current project.
If your project requires any Python packages, add a CondaPkg.toml
file to your project specifying what you need. Alternatively use CondaPkg.add()
to add dependencies from the REPL.
Writing packages which depend on PythonCall
Example
See https://github.com/cjdoris/Faiss.jl for an example package which wraps the Python FAISS package.
Precompilation
You may not interact with Python during module precompilation. Therefore, instead of
module MyModule
using PythonCall
const foo = pyimport("foo")
bar() = foo.bar() # will crash when called
end
you must do
module MyModule
using PythonCall
const foo = PythonCall.pynew() # initially NULL
function __init__()
PythonCall.pycopy!(foo, pyimport("foo"))
end
bar() = foo.bar() # now ok
end
Dependencies
If your package depends on some Python packages, you must write a CondaPkg.toml
file. See Installing Python packages.
Low-level API
The functions here are not exported. They are mostly unsafe in the sense that you can crash Julia by using them incorrectly.
PythonCall.pynew
— Functionpynew([ptr])
A new Py
representing the Python object at ptr
(NULL by default).
If ptr
is given and non-NULL, this function steals a reference to the Python object it points at, i.e. the new Py
object owns a reference.
Note that NULL Python objects are not safe in the sense that most API functions will probably crash your Julia session if you pass a NULL argument.
PythonCall.pyisnull
— Functionpyisnull(x)
True if the Python object x
is NULL.
PythonCall.pycopy!
— Functionpycopy!(dst::Py, src)
Copy the Python object src
into dst
, so that they both represent the same object.
This function exists to support module-level constant Python objects. It is illegal to call most PythonCall API functions at the top level of a module (i.e. before __init__()
has run) so you cannot do const x = pything()
at the top level. Instead do const x = pynew()
at the top level then pycopy!(x, pything())
inside __init__()
.
Assumes dst
is NULL, otherwise a memory leak will occur.
PythonCall.getptr
— Functiongetptr(x)
Get the underlying pointer from the Python object x
.
PythonCall.pydel!
— Functionpydel!(x::Py)
Delete the Python object x
.
DANGER! Use this function ONLY IF the Julia object x
could have been garbage-collected anyway, i.e. was about to become unreachable. This means you MUST KNOW that no other part of the program has the Julia object x
.
This decrements the reference count, sets the pointer to NULL and appends x
to a cache of unused objects (PYNULL_CACHE
).
This is an optimization to avoid excessive allocation and deallocation in Julia, which can be a significant source of slow-down in code which uses a lot of Python objects. It allows pynew()
to pop an item from PYNULL_CACHE
instead of allocating one, and avoids calling the relatively slow finalizer on x
.
PythonCall.unsafe_pynext
— Functionunsafe_pynext(x)
Return the next item in the iterator x
. When there are no more items, return NULL.