枚举类中的元组实例没有成员 (pylint no-member)。

9
我在使用枚举类的成员“value”和“equals”时,pylint会提示以下错误: “code”: “no-member” “message”: “Instance of 'tuple' has no 'value' member” 版本信息如下: pylint 2.3.1 astroid 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__的原因是什么? - dtrckd
1个回答

9

回答你的主要问题:

  1. pylint 无法识别 动态创建的属性,
  2. 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认为它是一个元组,而元组没有"value"成员。
回答是否有更多“pythonic”方法来达到同样的结果,我不确定您想要实现什么,但看起来有一些奇怪的事情正在发生。例如:
  1. __new__()的第一个参数是,但你把它叫做"self",这会让人非常困惑,因为根据(几乎)普遍的约定,"self"指的是一个实例。通常情况下,应该把它称为cls

  2. 单个下划线("_name", "_type")通常用于表示 "私有" 成员,所以在函数签名中使用它们会让大多数读者感到困惑。如果你想要使用保留字作为参数名,一种常见的约定是在其后面加下划线(例如 "type_", "exec_")。

  3. 我不知道你想通过"_type"属性实现什么样的目标,但现在无论是GlobalEnum.TRUE还是GlobalEnum.FALSE,它们的_type都会返回一个空字符串,因为str()返回一个字符串实例,没有参数时该字符串将为空。如果你希望它返回str类型,则应将其设置为str(不带括号)。

  4. 我认为你想创建一个枚举类型,其值在与你在定义中指定的int或字符串进行比较时将评估为True。在这种情况下,你可以重写内置的__eq__()魔术方法,以便你可以使用通常的==运算符,而不需要使用用户定义的equals()方法(你几乎肯定会在某个时候忘记使用它):

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只是一个普通的类属性,这意味着它可以被设置。如果要将其设置为只读,您可以使用 property decorator而不使用setter。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接