在Python中,如何获取扩展类元素以自动完成方式显示?

杰森·邓普曼

我是类的新手,因此使用一个在线示例来添加一些自定义日志记录级别。这将包含在一个库中,该库将导入到各种脚本中。它按预期工作,但添加的级别未显示在自动完成列表中(使用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
me

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

来自分类Java

IDEA和Eclipse:扩展类时如何自动生成方法

来自分类Dev

如何获取选项ID而不是自动完成组件中显示的字符串?

来自分类Dev

如何从XML标签中获取元素以存储到PHP数组中?

来自分类Python

重新排列矩阵元素以反映朴素python中的列和行聚类

来自分类Dev

如何在“自动完成”中找出所选元素的类别?

来自分类Dev

如何在IntelliJ中自动完成/导入Flutter类?

来自分类Dev

如何在IntelliJ中获取Vuetify样式标签自动完成

来自分类Dev

如何在JQuery自动完成中设置和获取ID

来自分类Dev

从Json中获取元素以在Picker中输入

来自分类Dev

如何在Matlab中获取矩阵的除第一个元素以外的所有元素?

来自分类Javascript

在javascript数组中,如何获取除第一个元素以外的最后5个元素?

来自分类Dev

Elixir-如何获取除列表中的最后一个元素以外的所有元素?

来自分类Dev

Xcode旧版本未显示“ Alamofire”及其自动完成方法

来自分类Python

如何在python中扩展类?

来自分类Dev

如何在Selenium Web Automation(Python)中遍历Web元素以从HTML标签提取文本?

来自分类Dev

获取元素以对齐

来自分类Dev

在类中获取元素?

来自分类Dev

如何以编程方式在CoordinatorLayout中显示折叠的元素?

来自分类PHP

如何用多个值拆分数组元素以在PHP中仅获取其中一个

来自分类Python

我如何在Sublime中为python库自动完成

来自分类Dev

如何使IntelliJ显示自动完成建议的Javadoc?

来自分类Dev

如何从自动完成文本框的自动建议中获取文本?

来自分类Dev

python如何以编程方式获取类定义的行号

来自分类Dev

在JQuery ui自动完成中显示图像

来自分类Dev

如何传递列表元素以在R中建模?

来自分类Dev

在zshell中获取pytest自动完成

来自分类Dev

在剑道自动完成中获取选定的对象

来自分类Dev

如何遍历元素及其子元素以顺序添加或删除类— Javascript / jQuery

来自分类Dev

获取活动选项卡项的元素以显示边界线

TOP 榜单

热门标签

归档