web-dev-qa-db-ja.com

タプルのインスタンスには、列挙型クラスにメンバーがありません(pylint no-member)

列挙型クラスのメンバー「value」と「equals」を使用すると、pylintから次のエラーが発生します。「code」:「no-member」「message」:「「Tuple」のインスタンスには「value」メンバーがありません」バージョン: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が他のことを報告したいので、クラスをホワイトリストに登録する場合も同じです調査結果。

8
Smule

主な質問に答えるには:

  1. pylint認識しない 動的に作成された属性、および
  2. Enum方法の数 で「特別」です。その1つは、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'>
_

つまり、TRUEGlobalEnumクラスに設定すると、PythonはTRUEGlobalEnumのインスタンスに変換します、しかし、pylintはこれを理解していません。また、_GlobalEnum.TRUE_にタプル値が割り当てられているように見えるため、pylintは、「値」メンバーを持たないタプルであると見なします。

同じ結果を達成するためのより「Python的な」方法があるかどうかに答えるために、あなたが達成しようとしていることはわかりませんが、あなたがしているいくつかの奇妙なことがあるようです。例えば:

  1. __new__()には、最初の引数としてclassが渡されますが、それを「自己」と呼んでいます。普遍的な規約はinstanceを参照しますが、これは読むのが非常に混乱します。通常はclsと呼びます。

  2. 通常、単一の先行アンダースコア( "__name_"、 "__type_")は、通常、「プライベート」メンバーを示すために使用されるため、ほとんどの読者にとって、関数のシグネチャでそれらを使用することは混乱します。予約済みのWordをパラメーター名として使用する場合、一般的な規則は末尾のアンダースコアを使用することです(例:「_type__」、「_exec__」)。

  3. 「__type_」属性で何を達成しようとしているのかわかりませんが、現在、_GlobalEnum.TRUE_と_GlobalEnum.FALSE_の両方が__type_として空の文字列を返しますstr()は文字列インスタンスを返すため、引数がないと文字列は空になります。 strtypeを返す場合は、str(かっこなし)に設定する必要があります。

  4. Ithinkあなたがしようとしていることは、指定したintまたは文字列と比較したときに値がTrueと評価される列挙型を作成することです定義で。その場合、ユーザー定義のequals()メソッド(ある時点で使用することはほぼ確実に忘れます)の代わりに、組み込みの__eq__()マジックメソッドをオーバーライドできます。代わりに通常の_==_演算子を使用できること:

_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 を使用できます。]

9
dizzy77