1

Suppose I define a package mypkg.py as follows:

import logging

class A:

    logger = logging.getLogger ('mylogger')

    def __init__(self):
        logger.warning ('initializing class A')

    def someMethod(self)
        logger.info ('about to do something useful')

if '__main__' == __name__:
    logger = logging.getLogger ('mylogger')
    a = A()

Sure enough, this works when I run it directly:

$ python3 mypkg.py
initializing class A

However, when I try to use the class from within an interactive session, the symbol logger is not available:

$ python3
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> logger = logging.getLogger ('mylogger')
>>> import mypkg
>>> a = mypkg.A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/mypkg.py", line 9, in __init__
    logger.warning ('initializing class A')
NameError: name 'logger' is not defined

I can 'fix' this by forcing logger to the global namespace:

import logging

class A:
    def __init__(self):
        global logger
        logger = logging.getLogger ('mylogger')
        logger.warning ('initializing class A')
        pass

now this works:

$ python3
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mypkg
>>> a = mypkg.A()
initializing class A

But surely this is not the right way to do this? What am I missing here?

Thanks, Mons

  • It is not the `global` that fixed it. A global is only global to a single file/module. In your first example, if you had said `self.logger.warning`, it would have worked fine. Your second example only works because `logger` is a global to that file. With logging, maybe it's not so important -- logging is a global service. – Tim Roberts Jun 23 '22 at 22:14
  • You **must** use `self` (or any reference to the instance) to access class state in a method. this is basic Python, I suggest you take a look at a basic tutorial on class definitions in Python, the [official one](https://docs.python.org/3/tutorial/classes.html). In this respect, it is different than other popular languages, like Java. In your version that "works" it's using the global reference from within the methods (which relies on running the `if __name__ == "__main__":` block – juanpa.arrivillaga Jun 23 '22 at 22:38
  • So in `__init__`, for example, you need `self.logger.warning ('initializing class A')` – juanpa.arrivillaga Jun 23 '22 at 22:41
  • @TimRoberts yeah, typically, logging is on a per-module basis in python, so usually you simply initialize a global logger in a module and use that global logger anywhere in the module that you require it. Some people coming from languages like Java balk at this, though. – juanpa.arrivillaga Jun 23 '22 at 22:46
  • Thanks @TimRoberts. In the actual code I'm debugging, I did update to use `self.logger()` before posting here, and when it didn't help, I made some unwarranted assumptions when setting up the minimal example above. After restarting my ipython session, it works as expected. And yes, I did try to re-import the module after edits. In summary, this question is moot, and thanks again for responding. – Mons Badonicus Jun 23 '22 at 22:56

1 Answers1

0

I think your supposed to use import logging not import logger or you havent installed logger. you can do this by pip install logger or logging idk

 def someMethod(self):
        logger.info ('about to do something useful')

should have a colon at the end when it is defined

zack
  • 39
  • 6