import logging logger = logging.getLogger(__name__)However, the general habit in other OOP programming languages (Java, C#, ...) is to have one (private static) logger per class:
public class MyObject { private final static Logger LOG = Logger.getLogger(MyObject.class.getName()); }In Python, a logger per class may be created, too:
import logging class Foo(object): __log = logging.getLogger(__name__ + '.Foo') def foo(self): self.__log.info('foo called') class Bar(Foo): __log = logging.getLogger(__name__ + '.Bar') def bar(self): self.__log.info('bar called') bar = Bar() bar.foo() bar.bar() >>> INFO:__main__.Foo:foo called >>> INFO:__main__.Bar:bar called
Note the double leading underscore
__log
to exploit the Python name mangling to simulate a private attribute.
However, it is not very convenient to write the name of the class as a string. One way to avoid that is to init the logger after the class has been created:
class Bar(Foo): def bar(self): self.__log.info('bar called') Bar._Bar__log = logging.getLogger(__name__ + Bar.__name__) # manual name manglingStill not very nice. We had to type the name of the class manually again. So let's exploit a decorator black magic to do it automatically:
def addlogger(cls: type): aname = '_{}__log'.format(cls.__name__) setattr(cls, aname, logging.getLogger(cls.__module__ + '.' + cls.__name__)) return cls @addlogger class Foo(object): def foo(self): self.__log.info('foo called') @addlogger class Bar(Foo): def bar(self): self.__log.info('bar called') bar = Bar() bar.foo() bar.bar() >>> INFO:__main__.Foo:foo called >>> INFO:__main__.Bar:bar calledAnd voilà, we have a private static logger for each class with just one simple line or code.