Search code examples
pythonpython-3.xcommand-line-interfacepypientry-point

Is there a better way to share variables between modules?


I'm making a package now and I want people can direct call this package so I'm using the entry point in setup.py.

Right now I have application.py which contains main() as the entry point. And the variable inside this main() function are sent to tex.py which helps me generate the latex report. (The way to generate latex file comes from this: Generating pdf-latex with python script)

# application.py
def main():
    a = 123
    b = 456
    from tex import generate
    generate()

#tex.py
content = f'{a} is not equal to {b}'
def generate():
    with open('report.tex','w') as f:
        f.write(content)

but this would lead to alb not defined.

I found one solution is to use global and add from application import * But since I have tens of variables, it'll be too long.

I wonder if there is a way to share the variables to my latex generator and keep this entry point feature.

Thanks in advance.


Solution

  • Like @juanpa.arrivilaga and @rv.kvetch suggested why not passing the arguments directly?

    # application.py
    def main():
      a = 123
      b = 456
      from tex import generate
      generate(a, b)
    
    #tex.py
    def generate(a, b):
      content = f'{a} is not equal to {b}'
      with open('report.tex','w') as f:
        f.write(content)
    

    Or if you have a lot of variables create a model and pass it

    class Model:
      __init__(a,b,c,d):
         self.a = a
         ....
    
        # application.py
    def main():
      a = 123
      b = 456
      from tex import generate
      generate(Model(a,b))
    
    #tex.py
    def generate(model):
      content = f'{model.a} is not equal to {model.b}'
      with open('report.tex','w') as f:
        f.write(content)
    

    Even better you can add the print logic into the model itself (using some associated methods), there so many solutions!

    class Model:
       ...init
        def __str__(self):
          return '{} is not equal to {}'.format(self.a, self.b)
    
        def __repr__(self):
          return '{} is not equal to {}'.format(self.a, self.b)