【问题标题】:Instance of tuple has no member (pylint no-member) in enum class元组的实例在枚举类中没有成员(pylint no-member)
【发布时间】:2019-08-21 07:17:21
【问题描述】:

在使用枚举类中的成员“value”和“equals”时,我从 pylint 收到以下错误: “代码”:“无成员” "message": "'tuple' 的实例没有 'value' 成员" 版本: 皮林特 2.3.1 小行星2.2.5 Python 3.6.3

代码按预期执行。我只是想知道我是否做错了什么(我不是专业的 python 程序员),或者是否有更“pythonic”的方式来实现相同的结果:

from enum import Enum

class DefaultEnum(Enum):

    def __new__(self,val,_name,_type):
        obj = object.__new__(self)
        obj._value_ = val
        obj._publicName = _name
        obj._type = _type
        return obj

    def __str__(self):
        return self._publicName

    def equals(self,_string):
        return _string == str(self)

class GlobalEnum(DefaultEnum):
    TRUE = 0,'True',str()
    FALSE = 1,'False',str()


GlobalEnum.TRUE.value
>> 0
GlobalEnum.TRUE.equals('True')
>> True
repr(GlobalEnum.TRUE)
>> <GlobalEnum.TRUE: 0>

我目前正在使用“# pylint: disable=no-member”注释来禁用警告,但我不希望这样做......将课程列入白名单也是如此,因为我仍然想要 pylint报告其他发现。

【问题讨论】:

  • 你使用__new__而不是__init__有什么原因吗?

标签: python python-3.x enums pylint


【解决方案1】:

回答你的主要问题:

  1. pylint doesn't recognize 动态创建的属性,以及
  2. Enumnumber of ways 中是“特殊的”,其中之一是 Enum 的成员实际上是 enum 类的实例:
    from enum import Enum

    class MyEnum(Enum):
        val1 = 0

    print(type(MyEnum.val1)) # <enum 'MyEnum'>


    class MyClass:
        val1 = 0

    print(type(MyClass.val1)) # <class 'int'>

也就是说,当您在 GlobalEnum 类中设置 TRUE 时,Python 会将 TRUE 转换为 GlobalEnum 的实例,但 pylint 不理解这一点,因为它看起来像 GlobalEnum.TRUE被分配了一个元组值,pylint 认为它是一个元组,它没有“值”成员。

要回答是否有更“pythonic”的方式来实现相同的结果,我不确定你想要完成什么,但看起来你正在做一些奇怪的事情。例如:

  1. __new__() 被传递了一个 class 作为它的第一个参数,但你称它为“self”,根据(近)通用约定,它指的是一个 instance ,读起来很费解。通常人们会称之为cls

  2. 单前导下划线(“_name”、“_type”)通常用于表示“私有”成员,因此在函数签名中使用它们会让大多数读者感到困惑。如果您想使用保留字作为参数名称,通常的约定是使用尾随下划线(例如,“type_”、“exec_”)。

  3. 我不确定你想用你的“_type”属性来完成什么,但现在GlobalEnum.TRUEGlobalEnum.FALSE都会返回一个空字符串作为他们的_type,因为str() 返回一个字符串实例,没有 args 字符串将为空。如果您希望它返回str 类型,则应将其设置为str(不带括号)。

  4. 认为您要做的是创建一个枚举,当与您在定义中指定的 int 或字符串进行比较时,其值将评估为 True。在这种情况下,您可以覆盖内置的 __eq__() 魔术方法,而不是用户定义的 equals() 方法(您几乎肯定会在某些时候忘记使用该方法),以便您可以使用通常的 @987654348 @ 运算符:

from enum import Enum


class BaseEnum(Enum):

    def __init__(self, int_value, str_value):
        self._value_ = int_value
        self.str_value = str_value

    def __eq__(self, other):
        return other == self.value or other == self.str_value


class MyEnum(BaseEnum):
    TRUE = 0, 'True'
    FALSE = 1, 'False'


print(MyEnum.TRUE == 0)  # True
print(MyEnum.TRUE == 'True')  # True
a = MyEnum.TRUE
print(a == MyEnum.TRUE) # True

print(MyEnum.TRUE.value)  # 0
print(MyEnum.TRUE.str_value)  # 'True'

[注意上面的str_value只是一个普通的类属性,意思是可以设置。要将其设为只读,您可以使用不带 setter 的 property decorator。]

【讨论】:

    猜你喜欢
    • 2021-05-24
    • 2020-09-22
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多