开发者

Is it good design to create a module-wide logger in python?

When coding python, I use the logging module a lot.

After some bad experiences and reading articles like this one, I try to prevent import-time executed code wherever possible.

However, for the sake of simplicity, I tend to get my logging object right at the beginning of the module file:

# -*- coding: utf-8 -*-
import logging
logger = logging.getLogger('product.plugin.foo.bar')

This way, my logger is globally accessible and I can just write "logger.error()" anywhere. The alternative is to create开发者_运维技巧 it class-wide:

class Bar(object):
    logger = logging.getLogger('product.plugin.foo.bar')

However, now I have to type the Class name everytime. To prevent typing the class name, I am tempted to use "self" instead, which will fail in static methods.

    def my_method(self):
        Bar.logger.error('foo')

    def my_method_2(self):
        self.logger.error('foo') # ok...

    @staticmethod
    def my_method_2():
        self.logger.error('foo') # boom!

So, at first, it looks like creating the logger object module-wide seems like the right thing to do - still it feels like I could end up in import-related trouble when doing it like this...


It's fine. I even use the same variable name logger. Any logging is better than no logging, but I find it's nice practise to only expose the logger variable, keep the module hidden away so your code only references the logger, and hence the namespace you've designated for the module.

If you later need to refine the namespaces for code within the module, you can use self.logger within those classes, or shadow the global logger where necessary.

Update0

__all__ = [anything but logger]
import logging
logger = logging.getLogger("why.is.this.method.still.java.camel.case")
del logging

Taking note of S.Lott's contribution below. Also note that generally you don't want from x import * anyway.


Damn - I realized it the second after I posted that question, that my "alternative" actually is not any different: the logger is created at import-time as well ;)

Still, I'm interested in your opinions on the best way to handle this issue. Another advantage of the first solution: We have some situations where we have to check on the availability of modules using import statements in try/except blocks. By creating the logger right at the beginning of the file, you can already use it to log this kind of events.


I would create the logger object at the beginning of the module and I would probably even use it in submodules if appropriate.

Anyway, I might still create an additional logging object inside a big class which uses logging a lot if I think it's a good idea - for example when i think it might be useful to configure the logging verbosity or the logging handlers separately for this important class (e.g. an class for ordering processes or for database queries might be such a case).

And you shouldn't worry about that your logging object is accessible outside the module. In fact, Python doesn't support private members at all. I think Guido van Rossum once wrote something like "We are all adults, aren't we?".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜