On 01/04/2023 02.01, Loris Bennett wrote:
Hi,

In my top level program file, main.py, I have

   def main_function():

       parser = argparse.ArgumentParser(description="my prog")

       ...

       args = parser.parse_args()
       config = configparser.ConfigParser()

       if args.config_file is None:
           config_file = DEFAULT_CONFIG_FILE
       else:
           config_file = args.config_file

       config.read(config_file)

       logging.config.fileConfig(fname=config_file)
       logger = logging.getLogger(__name__)

       do_some_stuff()
my_class_instance = myprog.MyClass()

   def do_some_stuff():

       logger.info("Doing stuff")

This does not work, because 'logger' is not known in the function
'do_some_stuff'.

However, if in 'my_prog/my_class.py' I have

   class MyClass:

       def __init__(self):

           logger.debug("created instance of MyClass")

this 'just works'.

I can add

   logger = logging.getLogger(__name__)

to 'do_some_stuff', but why is this necessary in this case but not in
the class?

Or should I be doing this entirely differently?

Yes: differently.

To complement @Peter's response, two items for consideration:

1 once main_function() has completed, have it return logger and other such values/constructs. The target-identifiers on the LHS of the function-call will thus be within the global scope.

2 if the purposes of main_function() are condensed-down to a few (English, or ..., language) phrases, the word "and" will feature, eg
- configure env according to cmdLN args,
- establish log(s),
- do_some_stuff(),  ** AND **
- instantiate MyClass.

If these (and do_some_stuff(), like MyClass' methods) were split into separate functions* might you find it easier to see them as separate sub-solutions? Each sub-solution would be able to contribute to the whole - the earlier ones as creating (outputting) a description, constraint, or basis; which becomes input to a later function/method.


* there is some debate amongst developers about whether "one function, one purpose" should be a rule, a convention, or tossed in the trash. YMMV!

Personal view: SOLID's "Single" principle applies: there should be only one reason (hanging over the head of each method/function, like the Sword of Damocles) for it to change - or one 'user' who could demand a change to that function. In other words, an updated cmdLN option shouldn't affect a function which establishes logging, for example.


Web.Refs:
https://people.engr.tamu.edu/choe/choe/courses/20fall/315/lectures/slide23-solid.pdf
https://www.hanselminutes.com/145/solid-principles-with-uncle-bob-robert-c-martin
https://idioms.thefreedictionary.com/sword+of+Damocles
https://en.wikipedia.org/wiki/Damocles

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to