# Passing a Julia function to a Python function

**URL:** <https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985>\
**Category:** General Usage\
**Created:** [January 3, 2022, 6:23pm UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985 "2022-01-03T18:23:03Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![krzysztofpostek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krzysztofpostek/32/32392_2.png) [@krzysztofpostek](https://discourse.julialang.org/u/krzysztofpostek)\
**Post date:** [January 3, 2022, 6:23pm UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985/1 "2022-01-03T18:23:03Z")

</div>

Hi there,

I want to use a GPyOpt Python package for Bayesian Optimization to find the minimum value of a function which is written in Julia. For that end, I try to use the PyCall.jl and to call the function as

function f(arg1::Float64, arg2::Float64)  
…  
end

py"“”  
domain = [{‘name’: ‘arg1’, ‘type’: ‘continuous’, ‘domain’: (-2.0, 5.0)}, {‘name’: ‘arg2’, ‘type’: ‘continuous’, ‘domain’: (-2.0, 5.0)}]  
“”"

And then to call the Python package as:  
gpyopt = pyimport(“GPyOpt.methods”)  
gpyopt.BayesianOptimization(f, py"domain")

However, this leads to the following error:  
ERROR: LoadError: (in a Julia function called from Python)  
JULIA: MethodError: no method matching (::var"#f#3644"{Array{Float64,2},Array{Float64,2},Int64,Int64})(::Array{Float64,2})  
Closest candidates are:  
f(!Matched::Float64, !Matched::Float64) at C:\Users\kpostek\Dropbox\Bi-level optimization\code\Heart dataset\BayesianOpt.jl:155

In general, passing a Julia function as an argument to a Python function seems to be difficult. Do you know any tricks for that? Re-coding the Julia function fully into Python is too much of a hassle…

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [January 3, 2022, 6:35pm UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985/2 "2022-01-03T18:35:31Z")

</div>

From the error message it looks like the Python function tries to call the julia function with four arguments, two matrices and two scalars, but you have only defined it for two scalars. Are you certain that you are using the package correctly?

Cf.

```julia
julia> using PyCall

julia> so = pyimport("scipy.optimize")
PyObject <module 'scipy.optimize' from '/home/gunnar/.local/lib/python3.8/site-packages/scipy/optimize/ __init__.py'>

julia> so.newton(x -> cos(x) - x, 1)
0.7390851332151607

julia> so.newton((x, y) -> cos(x) - x - y, 1)
ERROR: (in a Julia function called from Python)
JULIA: MethodError: no method matching (::var"#3#4")(::Float64)
Closest candidates are:
  (::var"#3#4")(::Any, !Matched::Any) at REPL[4]:1

```

---

<div class="post-metadata">

**Author:** ![krzysztofpostek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krzysztofpostek/32/32392_2.png) [@krzysztofpostek](https://discourse.julialang.org/u/krzysztofpostek)\
**Post date:** [January 4, 2022, 9:25am UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985/3 "2022-01-04T09:25:44Z")

</div>

Thanks! Indeed the way of using the package seems to be our problem. I don’t know how should I define the function/pass it in PyCall so that the whole thing works…

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [January 4, 2022, 9:47am UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985/4 "2022-01-04T09:47:41Z")

</div>

My best suggestion is that you first figure out how to use the package in Python with a radically simplified version of your objective function, then port the simplified function to Julia and get it to work via `PyCall`, and finally replace the simplified function with the real function. The simplified function can probably be completely trivial as long as it is in the same domain as your real function.

If you get stuck on the step from Python to `PyCall`, the simplified function should provide a Minimal Working Example that other people can run themselves to find where the problem is.

---

<div class="post-metadata">

**Author:** ![krzysztofpostek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krzysztofpostek/32/32392_2.png) [@krzysztofpostek](https://discourse.julialang.org/u/krzysztofpostek)\
**Post date:** [January 4, 2022, 12:39pm UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985/5 "2022-01-04T12:39:34Z")

</div>

Thanks a lot, it turned out that the way the input worked already on the Python level was somewhat un-intuitive!

---

<div class="post-metadata">

**Author:** ![xspeng](https://avatars.discourse-cdn.com/v4/letter/x/90ced4/32.png) [@xspeng](https://discourse.julialang.org/u/xspeng)\
**Post date:** [January 28, 2022, 11:11am UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-a-python-function/73985/6 "2022-01-28T11:11:20Z")

</div>

This post was temporarily hidden by the community for possibly being off-topic, unfocused, inappropriate, or spammy.
