# Using functions loaded via pycall (kwargs)

**URL:** https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775
**Category:** Tooling
**Tags:** pycall, python
**Created:** [August 22, 2025, 1:51pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775 "2025-08-22T13:51:25Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![Geegee](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Geegee](https://discourse.julialang.org/u/Geegee)
#### Post date: [August 22, 2025, 1:51pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/1 "2025-08-22T13:51:25Z")

</div>

I think this might be an easy thing but currently I don’t know how to do  
this. I managed to import my python code and can call it but part  
of the functions require me to do something like f(x=a, y=c, \*\*rest) and as  
Julia handles positional arguments differently I don’t know what to do really.  
I tried f(x, y, rest…) and f(x, y, PyDict(rest)…) but to no avail.

The next idea I had was to put everything into a python block:

```julia
py"""
def py_test(x):
    print(x)
    return
"""
py"py_test(noisy_data)"

```

but here the issue is that “noisy\_data” which I generated in Julia is not  
in the namespace. Is there a way to get access to Julia variables on that level?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 22, 2025, 3:53pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/2 "2025-08-22T15:53:50Z")

</div>

> [@Geegee](#):
>
> part  
> of the functions require me to do something like f(x=a, y=c, \*\*rest)

Can you give an explicit minimal example of a Python function signature you are trying to call?

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [August 22, 2025, 4:45pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/3 "2025-08-22T16:45:10Z")

</div>

> [@Geegee](#):
>
> but here the issue is that “noisy\_data” which I generated in Julia is not  
> in the namespace. Is there a way to get access to Julia variables on that level?

Sounds like you want to interpolate your variable, i.e. use `py"py_test($noisy_data)"`. For example,

```julia-repl
julia> d = Dict("a" => rand(5), "b" => 0);

julia> py"py_test($d)"
{'b': 0, 'a': array([0.57195721, 0.89319442, 0.96402566, 0.50358093, 0.19589507])}

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 22, 2025, 4:53pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/4 "2025-08-22T16:53:40Z")

</div>

> [@eldee](#):
>
> Sounds like you want to interpolate your variable, i.e. use `py"py_test($noisy_data)"`. For example,

I wouldn’t do it that way. Instead, I would just assign your Python function to a Julia variable and then call it normally as you would a Julia function:

```julia-auto
julia> py_test = py"py_test"
PyObject <function py_test at 0x1151bc160>

julia> py_test(3)
3

julia> x = 4
4

julia> py_test(x)
4

```

---

<div class="post-metadata">

### Author: ![Geegee](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Geegee](https://discourse.julialang.org/u/Geegee)
#### Post date: [August 23, 2025, 12:21pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/5 "2025-08-23T12:21:31Z")

</div>

Thanks that works. Should have thought of that!

---

<div class="post-metadata">

### Author: ![Geegee](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Geegee](https://discourse.julialang.org/u/Geegee)
#### Post date: [August 23, 2025, 12:22pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/6 "2025-08-23T12:22:39Z")

</div>

I would do that except I don’t know how kwargs from python translate to  
Julia. The function call unpacks a dictionary via the \*\* operator in python  
into the function. I need to replicate that on the Julia level if I am not missing something.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 23, 2025, 12:52pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/7 "2025-08-23T12:52:03Z")

</div>

Julia has keyword arguments too, which you can also splat:

```julia-auto
julia> py"""
       def foo(x, y):
           return 2*x + 3*y
       """

julia> foo = py"foo"
PyObject <function foo at 0x1675680d0>

julia> foo(3, 4) # call as positional
18

julia> foo(y=4, x=3) # call as keywords
18

julia> args = (; x=3, y=4)
(x = 3, y = 4)

julia> foo(; args...) # splat keywords
18

```

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [August 23, 2025, 12:52pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/8 "2025-08-23T12:52:06Z")

</div>

Do you want something like

```julia-repl
julia> py"""
       def py_f(a=1, b=2, **kwargs):
           if "c" in kwargs:
               return a + b + kwargs["c"]
           return a + b
       """

julia> f = py"py_f"
PyObject <function py_f at 0x00000243056A2440>

julia> f(1, 2)
3

julia> f(1, 2; c=3)
6

```

Edit: or

```julia-repl
julia> py"""
       def py_g(x, *, a, b, **rest):
           return x + 10 * a + 100 * b + 1000 * rest.get("c", 0) + 10_000 * rest.get("d", 0)
       """

julia> g = py"py_g"
PyObject <function py_g at 0x00000243056A27A0>

julia> g(1; d=5, a=2, b=3)
50321

```

?

---

<div class="post-metadata">

### Author: ![Geegee](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Geegee](https://discourse.julialang.org/u/Geegee)
#### Post date: [August 23, 2025, 6:59pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/9 "2025-08-23T18:59:53Z")

</div>

This would indeed be nicer. Thanks for your suggestions. I think it did teach me some things. Sadly with the function at hand it doesn’t work. I think I tried almost all permutations of your suggestions.

```python
fit_result = fit_model.fit(data=ydata, x=xdata, **fit_model.estimate(ydata, xdata))

```

This is the call signature of the python function. It is an lmfit model ( from lmfit the python package). ydata and xdata are python arrays and fit\_model.estimate returns a dictionary

```Julia
Dict{Any, Any} with 4 entries:
  "offset" => PyObject <Parameter 'offset', value=-0.00018379672152062232, bounds=[-1.0019158522526124:1.009325529… "phase" => PyObject <Parameter 'phase', value=-0.04986655005698104, bounds=[-3.141592653589793:3.14159265358979… "frequency" => PyObject <Parameter 'frequency', value=0.15873015873015872, bounds=[0:5.000000000000018]>
  "amplitude" => PyObject <Parameter 'amplitude', value=1.0056206910907135, bounds=[0:4.022482764362854]>

```

I am not sure if I want to invest much more time into the problem as the other way may not be so clean but it works, so I am kind of happy!.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 23, 2025, 7:25pm UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/10 "2025-08-23T19:25:58Z")

</div>

> [@Geegee](#):
>
> `fit_model.estimate` returns a dictionary

The problem is probably that a dictionary mapping _strings_ to values is not allowed for keyword arguments in Julia — if you want to splat, it needs to be something like a `NamedTuple`, or a dictionary mapping _symbols_ to values.

One option here would be to simply pass the keyword arguments explicitly rather than trying to splat them:

```julia-auto
estimate = fit_model.estimate(ydata, xdata)
fit_result = fit_model.fit(data=ydata, x=xdata, offset=estimate["offset"], amplitude=estimate["amplitude"])

```

Another option would be to make sure you treat the returned dictionary as having symbols for keys. You can do this via the lower-level function `pycall`, which lets you specify the desired function return type. For example:

```julia-auto
estimate = pycall(fit_model.estimate, PyDict{Symbol,PyAny}, ydata, xdata)
fit_result = fit_model.fit(; data=ydata, x=xdata, estimate...)

```

The basic lesson here is that you need to understand how Python types relate to Julia types, and you sometimes need to specify the desired type conversion explicitly rather than relying on PyCall’s auto-conversion.

(Another package, PythonCall.jl, never auto-converts Python objects to native Julia types at all, so you _always_ have to convert explicitly.)

---

<div class="post-metadata">

### Author: ![Geegee](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Geegee](https://discourse.julialang.org/u/Geegee)
#### Post date: [August 24, 2025, 5:36am UTC](https://discourse.julialang.org/t/using-functions-loaded-via-pycall-kwargs/131775/11 "2025-08-24T05:36:33Z")

</div>

Wow good spot there! Never would have figured that out. Now it works!
