Using dot syntax and Symbols from Python

Is there a convenient way to use functions that make use of the dot syntax, as well as Symbols using juliacall (or alternatively pyjulia)?

(Example code utilizing JuMP, after from juliacall import Main as jl) I know I can do:

# python code:
jl.seval("JuMP.value.(model.ext[:myvariable])")

This is rather non-elegant, and I can’t find out how to call the broadcasted version of JuMP.value?!

Ideally I am looking to do something similar like calling ...! functions (via ..._b), like:

# python code:
myvariable = jl.seval(":myvariable")
v = jl.JuMP.value_d(model.ext[myvariable])
1 Like

You can do this:

In [21]: from juliacall import Main as jl

In [22]: jl.seval("using JuMP")

In [23]: JuMp = jl.seval("JuMP")

In [24]: JuMp.value  # TAB completion works
Out[24]: value (generic function with 15 methods)

In [26]: jl.seval("struct B x end")

In [27]: B = jl.seval("B")

In [28]: b = B(2)

In [29]: b.x  # TAB completion works in ipython
Out[29]: 2

In juliacall Julia modules are available in Python as instances of juliacall.ModuleValue. They are not really Python types or classes.

On the other hand, pyjulia (the julia module) makes Python modules out of Julia modules:

In [13]: from julia import JuMP

In [14]: JuMP.value
Out[14]: <PyCall.jlwrap value>

# JuliaModule is a subclass of the Python class (or type) ModuleType

In [15]: type(JuMP)
Out[15]: julia.core.JuliaModule

In [16]: from types import ModuleType

In [17]: isinstance(JuMP, ModuleType)
Out[17]: True

I am not really sure why that would be a disadvantage in my case?

I don’t think it’s a necessarily a disadvantage. They both allow you to use dots, but in terms of the Python types, they are very different. I don’t know if one is better than the other or why.

1 Like

I’d use seval to create an anonymous function to do the broadcasting, like so:

f = jl.seval("x->JuMP.value.(x)")
v = jl.Symbol("myvariable")
f(model.ext[v])

This way the function f (and symbol v) can be computed once, but called many times.

Creating an anonymous function like this is a good way to access Julia semantics (such as broadcasting or macros) not otherwise exposed by JuliaCall.

2 Likes