1

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.

Tylerastro
  • 43
  • 5
  • You can create a global namespace (maybe a `dataclass`) and put all your variables under there. You can also start the class name with an underscore to mark it as private, then create a singleton variable of this dataclass which can be shared between modules. No need to use `global` with such an approach. – rv.kvetch Sep 07 '21 at 04:32
  • 6
    The best way is to *explicitly provide arguments to `generate`* – juanpa.arrivillaga Sep 07 '21 at 04:32
  • @rv.kvetch why not just a regular module? – juanpa.arrivillaga Sep 07 '21 at 04:32
  • hmm, not sure if I’m following you – rv.kvetch Sep 07 '21 at 04:35
  • oh, well if I understand correctly, the OP mentioned he has a lot of variables, so he wants to avoid long lines of imports – rv.kvetch Sep 07 '21 at 04:36
  • star imports are also painful to write in this case. because you’ll have to define variable names twice (once again in `__all__` which probably not worth it if you have a ton of variables) – rv.kvetch Sep 07 '21 at 04:39
  • Thank you for your helpful comments. Now I use a function to have those inputs. – Tylerastro Sep 10 '21 at 01:19

1 Answers1

2

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)
CloudBalancing
  • 1,461
  • 2
  • 11
  • 22
  • Yes, these are good solutions. I was wondering if there is a more efficient or cleverer way because it's my first time to write a package. Thanks for answering. – Tylerastro Sep 10 '21 at 01:18