How to evaluate Python custom code in PythonCall?

While I agree that most “call Python in Julia” refers to call existing libraries, I sometimes find it useful to be able to evaluate custom defined Python code from Julia.

Which is the PythonCall equivalent to this PyCall snippet ?

using PyCall
py"""
def sumMyArgs (i, j):
  return i+j
def getNElement (n):
  a = [0,1,2,3,4,5,6,7,8,9]
  return a[n]
"""

a = py"sumMyArgs"(3,4)          # 7
b = py"sumMyArgs"([3,4],[5,6])  # [8,10]
c = py"sumMyArgs"([3,4],5)      # [8,9]
d = py"getNElement"(1)          # 1

See the related topic:

yep… indeed, same need… thanks

This is a way to do:

using PythonCall, Pipe

i = 3
@pyexec (i=i, j=4) => """
a=i+j
b=i/j
""" => (a::Int64,b::Float64)
typeof(a)

@pyexec """
def python_sum(i, j):
    return i+j
""" => python_sum
@pyexec """
def get_ith_element(n):
    a = [0,1,2,3,4,5,6,7,8,9]
    return a[n]
""" => get_ith_element

c = @pipe python_sum(3,4) |> pyconvert(Int64,_)       # 7
d = @pipe python_sum([3,4],[5,6]) |> pyconvert(Vector{Int64},_) # [8,10]
typeof(d)                       # Array{Int64,1}
e = @pipe get_ith_element(i) |> pyconvert(Int64,_) #3
1 Like

How to import local custom python code library in Julia? I have a python file which i will need for running Julia code.

Good question… I don’t have the answer, but the other way around is:

>>> from juliacall import Main as jl
>>> jl.seval("include(\"julia_code.jl\")")

I am looking at PythonCall “seriously” for the first time, and while I like some aspects (one Python env for each Julia project is awesome) there are others much less nice… why don’t just let evaluate custom Python code in Python (like in PyCall py"“…”") instead of using lots of newly named functions ? Also, why pyconvert instead of just overriding convert ?

If you find the way, please post the answer here :wink:

Here it is… …weird syntax…

Assume you have a python_code.py file with the following content:

def python_sum(i, j):
    return i+j

def get_ith_element(n):
    a = [0,1,2,3,4,5,6,7,8,9]
    return a[n]

You can then “import” it and call the individual functions defined there with:

i = 3
pyexec(read("python_code.py", String),Main)
@pyexec (i=3, j=4) => "f = python_sum(i,j)" => (f::Float64)

I still need to understand how to convert a Julia object in a Python one, for example an Array… I know that when using np operations the conversion is done automatically (and possibly without copying, that’s the nice thing) but I may want to use also python functions that weren’t in the tought of the JuliaCall developers, so in Python I would like to end up with a Python object…

I got how to convert the Julia object into a Python one… writing it here for reference…

When you call in Python a Julia function, the object you have is:

  • for primitive, immutable scalars, the primitive equivalent of python
  • for arrays and mutable types, a Python object that wrap the Julia one.

While this object, in the case of arrays, supports the Numpy interface, it may not be accepted by functions that want a “real” numpy array. In such circumstances it can be converted to “real” numpy array with obj.to_numpy().

1 Like