Accessing Objects Created in PyScript from JavaScript

I’ve found a way of binding a JavaScript variable to a Python object created in PyScript by using Javascript’s eval() method. I can’t imagine this is the best way to do this, but I thought it was interesting, and maybe useful to others exploring related topics down the road.

We create a Javascript function that takes an object and a string, and uses eval() to bind that object to a new variable with that string as it’s name.

<script>
    function createObject(x, variableName){
        let execString = variableName + " = x"
        console.log("Running `" + execString + "`");
        eval(variableName + " = x")
    }
</script>

Then in PyScript, we call that function with the object’s we’d like to pass and their name

<py-script>
    import js
    from pyodide import create_proxy, to_js

    names = ["Jeff Glass"]
    js.createObject(create_proxy(names), "names")

    multiplier = lambda z: z * 2
    js.createObject(create_proxy(multiplier), "multiplier")

    console.log(to_js(js.names))
    console.log(js.multiplier(5))
</py-script>

image

Then if we mutate any of the Python objects, we can see the change reflected in JavaScript.

Of course the Javascript variable is bound to the Python object, not the Python variable name. Here:

  • the list names is mutated, but
  • the variable python variable multiplier is now points to the new lambda function
  • while the Javascript variable multiplier still points to the original lambda function:
# continued from above
<py-script>
    names.append("John Hanley")
    console.log(to_js(js.names))

    multiplier = lambda z: z * 100000
    console.log(js.multiplier(5))
</py-script>

image

1 Like