我是类的新手,因此使用一个在线示例来添加一些自定义日志记录级别。这将包含在一个库中,该库将导入到各种脚本中。它按预期工作,但添加的级别未显示在自动完成列表中(使用PyCharm),并且PyCharm抱怨LOGGER中有未解决的属性引用。当我编码时,输入“ LOGGER”。我看到正常的错误,警告,信息等可供选择,但我的自定义级别“详细”不在列表中。随着时间的流逝,将会添加更多的自定义级别,并且还将向一组开发人员推出,因此我需要进行这项工作。
知道为什么在我的自动完成列表中没有verbose选项吗?
这是我的文件。
px_logger.py
from logging import getLoggerClass, addLevelName, setLoggerClass, NOTSET
public class PxLogger(getLoggerClass()):
def __init__(self, name, level=NOTSET):
super(PxLogger, self).__init__(name, level)
addLevelName(5, "VERBOSE")
def verbose(self, msg, *args, **kwargs):
"""Custom logger level - verbose"""
if self.isEnabledFor(5):
self._log(5, msg, args, **kwargs)
my_script.py
import json
import logging.config
from px_logger import PxLogger
logging.setLoggerClass(PxLogger)
LOGGER = logging.getLogger(__name__)
with open('../logging.json') as f: # load logging config file
CONFIG_DICT = json.load(f)
logging.config.dictConfig(CONFIG_DICT)
LOGGER.verbose('Test verbose message')
屏幕输出
VERBOSE - Test verbose message
PyCharm提供了多种方法来完成类型提示
在内部,它使用Typeshed确定标准lib对象和常见的3rd party包的类型。这也是PyCharm从中获取logging.getLogger的返回值类型的原因,这就是为什么它不会verbose
在autocomplete中显示子类的方法的原因,因为它假定LOGGER
是的实例logging.Logger
。
告诉PyCharm的类型检查器LOGGER
作为其实例的最简单方法是PxLogger
分配期间代码中的类型注释。这仅适用于Python 3.5+:
LOGGER: PxLogger = logging.getLogger(__name__)
如果更进一步,您将封装自定义记录器类的定义,将其定义为全局记录器类,并将其定义为logging.getLogger
模块内部的包装器。
这样,您的同事就可以导入模块,而不必logging
像导入原始模块一样使用它,logging
而不必担心将哪个类设置为logger类或如何注释保存其logger的变量。
当沿着这条路走时,有三个选项可以为类型检查器包括类型提示。
px_logger.py
# basically, import from logging whatever you may need and overwrite where necessary
from logging import getLogger as _getLogger, Logger, addLevelName, setLoggerClass, NOTSET
from typing import Optional # this only for the Python 3.5+ solution
class PxLogger(Logger): # Note: subclass logging.Logger explicitly
def __init__(self, name, level=NOTSET):
super(PxLogger, self).__init__(name, level)
addLevelName(5, "VERBOSE")
def verbose(self, msg, *args, **kwargs):
"""Custom logger level - verbose"""
if self.isEnabledFor(5):
self._log(5, msg, args, **kwargs)
setLoggerClass(PxLogger)
"""
Possible approaches, implement one of the below.
The first is Python 3.5+ only.
The second and third work for both, Python 2 and Python 3.
"""
# using type annotation syntax (py35+)
def getLogger(name: Optional[str]=None) -> PxLogger:
_logr: PxLogger = _getLogger(name)
return _logr
# using (legacy) docstring syntax (py2and3)
def getLogger(name=None)
"""
:param name: str
:rtype: PxLogger
"""
return _getLogger(name)
# using a stub file (py2and3)
def getLogger(name=None):
return _getLogger(name)
Python 2and3存根文件方法需要在包中py_logger.pyi
实际模块文件旁边的文件名为px_logger.py
。
px_logger.pyi
# The PEP-484 syntax does not matter here.
# The Python interpreter will ignore this file,
# it is only relevant for the static type checker
import logging
class PxLogger(logging.Logger):
def verbose(self, msg, *args, **kwargs) -> None: ...
def getLogger(name) -> PxLogger: ...
对于这三种方法,您的模块my_script
看起来都一样:
my_script.py
import logging.config
import px_logger
LOGGER = px_logger.getLogger(__name__)
# I used basicConfig here for simplicity, dictConfig should work just as well
logging.basicConfig(level=5,
format='%(asctime)s - %(levelname)s [%(filename)s]: %(name)s %(funcName)20s - Message: %(message)s',
datefmt='%d.%m.%Y %H:%M:%S',
filename='myapp.log',
filemode='a')
LOGGER.verbose('Test verbose message')
自动完成功能可与以下三种方法很好地配合使用:
方法2和3已在PyCharm 2018.1 CE中使用Python 2.7.15和3.6.5进行了测试
注意:在此答案的先前版本中,我说过docstring方法虽然显示了verbose()
PxLogger类的自定义方法,但缺少了基类的方法。那是因为您从任何logging.getLoggerClass
返回值(即任意类)派生PxLogger 。如果使PxLoggerlogging.Logger
显式地成为子类,则类型检查器将知道基类,并且可以正确解析其方法以实现自动补全。
getLoggerClass
无论如何,我不建议对返回值进行子类化。您将要确定自己从中得到什么,而不要依赖于返回正确内容的函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句