简体   繁体   中英

Python relative/absolute import (again)

This topic has been covered several times but I still can't get my package to work. Here is the situation: I've got a package in which a logging module takes care of setting up the logging. So clearly, mypackage.logging conflicts with Python logging from the standard library.

The directory' structure:

├── mypackage
│   ├── __init__.py
│   ├── logging.py
└── script.py

mypackage.__init__

import logging
from . import logging as _logging

logger = logging.getLogger(__name__)

def main():
    _logging.init_logging()
    logger.info("hello")

mypackage.logging

"""logging - Setup logging for mypackage."""

import copy
import logging
import logging.config


_DEFAULT_LOGGING_CONFIG_DICT = {
    'version': 1,

    'formatters': {
        'verbose': {
            'format': '%(asctime)s - %(name)s::%(levelname)s: %(message)s',
        },
        'simple': {
            'format': '-- %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'simple',
        },
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'oprpred.log',
            'mode': 'w',
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'oprpred': {
            'level': 'INFO',
        },
    },
    'root': {
        'level': 'INFO',
        'handlers': ['console', 'file'],
    },
}

def init_logging(verbose=False):
    """Initialize logging.

    Set the log level to debug if verbose mode is on.
    Capture warnings.
    """
    d = default_logging_dict()
    if verbose:
        d['root']['level'] = 'DEBUG'
        d['loggers']['oprpred']['level'] = 'DEBUG'
    logging.config.dictConfig(d)
    logging.captureWarnings(True)


def default_logging_dict():
    return copy.deepcopy(_DEFAULT_LOGGING_CONFIG_DICT)

script.py

import mypackage
mypackage.main()

Finally, this is the error message I'm getting:

$ python3 script.py                                                                                                                                                                     [11:09:01]
Traceback (most recent call last):
  File "script.py", line 4, in <module>
    mypackage.main()
  File "/Users/benoist/Desktop/test_logging/mypackage/__init__.py", line 8, in main
    _logging.init_logging()
AttributeError: module 'logging' has no attribute 'init_logging'

Final remark, I noticed that if in mypackage.__init.py__ I import mypackage.logging prior to the standard library logging , it works. I don't want to do that since it is against Python PEP8 recommandations:

Imports should be grouped in the following order:

  1. standard library imports
  2. related third party imports
  3. local application/library specific imports

Any help would be greatly appreciated.

Ben.

PS I'm using Python 3.5.1.

The way I deal with this specific issue of using a custom logging module is to import all the logging functions into my custom module. Now you can also reimplement module level functions with customized versions as well.

For example:

"""logging - Setup logging for mypackage."""

import copy
from logging import *
import logging.config


_DEFAULT_LOGGING_CONFIG_DICT = { ... }

def init_logging(verbose=False):
    ...

def default_logging_dict():
    ...

Now you only need to import your custom module.

from . import logging

log = logging.getLogger()


An alternative to using from logging import * is to reimplement any commonly used functions from the built in logging module.

import copy
import logging

def getLogger(*args, **kwargs):
    logging.getLogger(*args, **kwargs)

If you need to reach logging function that you have not reimplemented you can call through to the builtin logging module, for example: logging.logging.addLevelName(...) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM