Context: I have a Pluto notebook for teaching where I need to create a Python function. I want to use PythonCall for better portability, but I miss the py"..."
syntax of PyCall which allows you to directly define Python functions inside Julia code. Is there a workaround to importing the function from a file? I looked at @py
but it doesn’t seem to work for my case.
Do you require the function to be defined in Python, or could you use something like pyfunc
as described in Reference - PythonCall - Create classes ?
Ideally I’d want the function to be defined in Python to demonstrate the Julia speed up. Dumping on Python is my favorite pastime
julia> using PythonCall
julia> fib(x) = pyexec("""
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
fib(y)
""", Main, (y=x,))
fib (generic function with 1 method)
julia> fib(10)
0 1 1 2 3 5 8
https://cjdoris.github.io/PythonCall.jl/stable/pythoncall-reference/#PythonCall.pyexec
Thanks a bunch!
For future reference, we don’t need to redefine the Python function every time we call the Julia one, we can also access local variables within it:
julia> fib(n) = pyexec(
@NamedTuple{a::Int},
"""
a, b = 0, 1
for k in range(n):
a, b = b, a + b
""",
Main,
(n=n,)
)
fib (generic function with 1 method)
julia> fib(10)
(a = 55,)
Whenever you use pyexec
you’re invoking the Python parser, which makes for an unfair comparison. It’s better to use it to create a Python function then call that:
@pyexec """
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
""" => fib
fib(10)
This example uses @pyexec
’s handy =>
notation for getting variables into and out of Python.
Thanks, that’s exactly what I was looking for
Thanks for the great extension to the PythonCall doc! What I can’t get to work yet is an import within the literal code, or some way to get an import (e.g. numpy) to work in or around your fibonacci. There must be a way?
Thanks for any tips!
@cjdoris sorry for the necroposting but I find myself interested in this question again. Is there a way to achieve that?