【问题标题】:How to get Intellisense working with custom python enum which uses a classproperty decorator如何让 Intellisense 使用使用类属性装饰器的自定义 python 枚举
【发布时间】:2020-04-09 07:21:16
【问题描述】:

我正在尝试以一种可以很好地使用文档字符串的方式在 python 中实现枚举。

基本上这就是我正在做/尝试做的事情(由于其长度,完整的可运行代码将位于底部):

class Animals(EnumBase):
    _dog = 'Dog'
    _cat = 'Cat'

    @classproperty
    def dog(cls):
        """
        A four legged creature that loves humans too much.
        """
        return cls._dog

    @classproperty
    def cat(cls):
        """
        Rules over humans.
        """
        return cls._cat

print(Animals.dog) # Outputs 'Dog' so programmatically works perfect

我的代码在技术上运行良好,但是 VS Code Intellisense 无法读取枚举的文档字符串。例如,当我将鼠标悬停在print(Animals.dog) 中的dog 上时,它不会输出其文档字符串。我认为这是因为 classproperty 装饰器,但我不知道更好的方法(除非我切换到 classmethods 但我想避免 unneeded 括号)。

任何人都有更好的方法来完成此任务,或者我不能欺骗 Intellisense 读取我的文档字符串吗?

完整的可运行代码如下。请注意,还有许多与当前问题无关的其他功能(基本上是允许我将子类视为可迭代对象的代码)。

class classproperty(property):
    """
    Class method property decorator. (Used via @classproperty)
    A @classmethod allows us to call stuff from classes like:
    Foo.bar()
    A @property allows us to call functions like:
    Foo().bar
    But we want enum functionality with doc strings like:
    Foo.bar
    Thus the usecase of this decorator.
    """
    def __get__(self, cls, owner):
        """
        Redefining get.
        """
        return classmethod(self.fget).__get__(None, owner)()

class _MetaEnum(type):
    """
    Meta class needed to overload the __contains__ method for
    EnumBase.
    """
    def __contains__(cls, val):
        """
        Opertator overload for the `in` operator at a class level.
        Will return true if `x` is one of the enum values
        stored in the child class of the base class.
        """
        return val in cls._get_contents()

    def __str__(cls):
        """
        String operator overload.
        """
        return ', '.join(str(x) for x in cls._get_contents())

    def __iter__(cls):
        """
        Returns a generator for all elements in a class.
        """
        return (x for x in cls._get_contents())

class EnumBase(metaclass=_MetaEnum):
    """
    An enum base class that can be inherited by Enum classses.
    Allows the `in` operation to be perform as well as auto str formatting.
    Example:
    class Foo(EnumBase):
        a = 2
        b = 3
        c = 4
    print(2 in Foo) # True
    print(Foo) # 2, 3, 4
    """
    @classmethod
    def _get_contents(cls):
        """
        Returns a set of all different enum values.
        """
        # Get all class attributes that are not methods
        attributes = inspect.getmembers(cls, lambda a: not inspect.isroutiane(a))

        # Turn all attributes that aren't private (such as __dict__) to a set
        # and return it.
        return {a[1] for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))}

class Animals(EnumBase):
    _dog = 'Dog'
    _cat = 'Cat'

    @classproperty
    def dog(cls):
        """
        A four legged creature that loves humans too much.
        """
        return cls._dog

    @classproperty
    def cat(cls):
        """
        Rules over humans.
        """
        return cls._cat

【问题讨论】:

  • Python 从 3.4 版开始有一个实际的Enum。您是否尝试过将其与 IntelliSense 一起使用?

标签: python python-3.x visual-studio-code decorator docstring


【解决方案1】:

基本上,您无法欺骗 IntelliSense 引擎将您的装饰器识别为将方法转换为描述符。

【讨论】:

  • 这是我的猜测,但我希望我错了。我尝试了一大堆其他的东西,包括试图改变我做元类的方式,但即使我得到 __doc____name__ 来正确填充 IntelliSense 失败......除了 IntelliSense 一切都按预期工作。至少感谢您确认。万一有人发现漏洞,我将不予答复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 2017-04-02
相关资源
最近更新 更多