View Source Pythonx.Encoder protocol (Pythonx v0.4.4)
A protocol for converting data structures to Python objects.
The protocol has implementation for Elixir built-in data types.
In order to define it for other data structures, you can use Pythonx.eval/2
and pass necessary information as built-in types. For example, imagine
we have the following struct representing a complex number:
defmodule Complex do
defstruct [:re, :im]
end
The protocol implementation could look like this:
defimpl Pythonx.Encoder, for: Complex do
def encode(complex, _encoder) do
{result, %{}} =
Pythonx.eval(
"""
complex(re, im)
""",
%{"re" => complex.re, "im" => complex.im}
)
result
end
end
Pythonx.encode!(%Complex{re: 1, im: -1})
#=> #Pythonx.Object<
#=> (1-1j)
#=> >
When dealing with more complex data structures, you will want to
return an object from a Python package. In that case, it is a good
idea to raise a clear error if the package is not installed. For
example, here is one possible implementation for Explorer.DataFrame
:
defimpl Pythonx.Encoder, for: Explorer.DataFrame do
def encode(df, _encoder) do
{result, %{}} =
Pythonx.eval(
"""
try:
import polars
result = polars.read_ipc(ipc)
except ModuleNotFoundError:
result = None
result
""",
%{"ipc" => Explorer.DataFrame.dump_ipc!(df)}
)
case Pythonx.decode(result) do
%Pythonx.Object{} ->
result
nil ->
raise Protocol.UndefinedError,
protocol: @protocol,
value: df,
description:
"cannot encode Explorer.DataFrame, because the polars Python package is not installed"
end
end
end
Summary
Functions
A function invoked to encode the given term to Pythonx.Object
.
Types
@type t() :: term()
All the types that implement this protocol.
Functions
@spec encode(term :: term(), Pythonx.encoder()) :: Pythonx.Object.t()
A function invoked to encode the given term to Pythonx.Object
.