2016-06-09 81 views
4

本主題已被多次覆蓋,但仍無法讓我的軟件包正常工作。 這裏是情況:我有一個包,其中logging模塊負責設置日誌記錄。 很明顯,mypackage.logging與標準庫中的Python logging衝突。Python相對/絕對導入(再次)

目錄」結構:

├── 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() 

最後,這是我收到錯誤消息:

$ 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' 

最後再說一句,我注意到,如果在mypackage.__init.py__我進口mypackage.logging標準庫logging之前,它的工作原理。 我不想這樣做,因爲這是對Python的PEP8 recommandations:

進口量應按照下列順序進行分組:

  1. 標準庫進口
  2. 相關第三方進口
  3. 本地應用程序/庫特定進口

任何幫助將不勝感激。

本。

P.S.我正在使用Python 3.5.1。

+0

如果您將'_logging'和您自己的日誌記錄模塊導入標準日誌記錄模塊爲'logging',它應該可以工作。一般來說,你在'__init __。py'中從你自己的包中導入的任何東西都應該通過它的真實名稱導入,而且你不應該用任何東西來映射這些名字。儘管如此,我沒有可以測試的Python 3安裝。 – user2357112

回答

0

我處理這個使用自定義日誌模塊的特定問題的方式是將所有日誌記錄功能導入到我的自定義模塊中。現在您還可以使用自定義版本來重新實現模塊級功能。

例如:

"""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(): 
    ... 

現在你只需要導入您的自定義模塊。

from . import logging 

log = logging.getLogger() 


使用from logging import *的替代方法是從內置在記錄模塊重新實現任何常用的功能。

import copy 
import logging 

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

如果你需要達到你有沒有重新實現,你可以通過調用內置的日誌模塊,例如記錄功能:logging.logging.addLevelName(...)

+0

我想這會工作。由於'from logging import *'是非常不安全的,因此不推薦這樣做,因此在我看來這是一個「髒伎倆」。 – blaurent

+0

另一個選擇是使用'import logging',然後重新實現你經常使用的任何函數,特別是'getLogger()'。通過調用('logging.logging.setLevel(...)'),您仍然可以訪問任何日誌記錄例程。 – amicitas

+0

感謝您的建議。我很驚訝沒有人回答這個問題。如果你提出的解決方案是這樣做的官方好方法,那麼我認爲它很老實。我不習慣Python的醜陋解決方案,所以我很驚訝! – blaurent