Search code examples
javascriptpythonbrython

Brython: Calling Methods of objects from a seperate python file


I'm quite new to the Brython framework, so my question will be a basic one. Apologies for that.

Here is my script "log.py":

import math

class Logarithm:
    def__init__(self,x,y):
        self.x = x
        self.y = y

    def log(x,y):
        return math.log(x[,y])

And in html:

        <script src = "https://cdnjs.cloudflare.com/ajax/libs/brython/3.3.20/brython_stdlib.js"></script>

        <script src = "log.py" type = "text/python"></script>
        <script>
             //some javascript code
        </script>

Now , in my javascript, I want to call the log() function of the Logarithm class. Can anyone tell me how can I accomplish this?

Thanks in advance :-)


Solution

  • Brython allows you to write Python in the browser directly - but that implies you have to know what you are doing on the Python side. Your snippet is syntactically incorrect Python. When we fix the syntax, we have to fix it so that it makes some sense - (so, if you are taking x and y at class construction time as the logarithm operand and base, you don't want then again when using the log).

    And then, when we fix that, you have to fix the html part so that it can make use of Brython properly. Then you are set to go with what you want. Always look at the Javascript console output (ctrl + F12) - Brython can generate some usefull traceback, once it is loaded, telling of errors on the Python code.

    And then you have to keep in mind that although Brython authors have made it almost transparent to call Python functions from normal Javascript, with the provisions bellow, that does not work in such a straightforwared transparent way for classes and methods - which you attempt to use.

    TL;DR: for whoever already have some Brython code working and wants to call Brython functions from Javascript, just do on the Brython code:

    def my_func(...):
        ...
    
    from browser import window
    window.my_func = my_func
    

    And you can now use "my_func" from plain Javascrit script blocks, but you have to allow sometime for Brython to load and run its code - any javascript using Brython must be called a while after the onload event runs the main brython function. See the example bellow.

    So, in your case, we can rewrite the log.py file to be:

    import math
    
    class Logarithm:
        def __init__(self, x, y=10):
            self.x = x
            self.y = y
    
        def log(self):
            return math.log(self.x,self.y)
    
    
    from browser import window
    window.Logarithm = Logarithm
    

    And then, we have to proper write the html file to load main Brython and the Python stdlib as two separate script tags, activate brython on the onload event, and then we are ready to go:

    <html>
      <head>
        <script src="http://brython.info/src/brython.js"></script>
        <script type="text/javascript" src="http://brython.info/src/brython_stdlib.js"></script>
        <script src="log.py" type="text/python3"></script>
        <script type="text/javascript">
            function do_python() {
                var obj = window.Logarithm(100, 10);
                var result = obj.__class__.log(obj);
                document.write(result);
            }
        </script>
      </head>
      <body onload="brython(); setTimeout(do_python, 300)">
    
      </body>
    </html>
    

    Note that the Javascript actually calling the Brython class is wrapped in a setTimeout call. This allows Brython to set things up. And although you can create an instance of the Brython object by simply calling the class, to call methods on it you have to manually call then on the __class__ attribute, and pass the instance explicitly as the first parameter.

    The mechanism to find the method name in the class and add the self parameter automatically is used only when the instance is used from Brython.