web-dev-qa-db-fra.com

L'instance de Tuple n'a pas de membre (pylint no-member) dans la classe enum

J'obtiens les erreurs suivantes de pylint lors de l'utilisation des membres "value" et "equals" d'une classe enum: "code": "no-member" "message": "L'instance de 'Tuple' n'a pas de membre 'value'" Versions: pylint 2.3.1 astroid 2.2.5 Python 3.6.3

Le code est exécuté comme prévu. Je me demande simplement s'il y a quelque chose que je fais mal (je ne suis pas un pro python), ou s'il existe un moyen plus "Pythonic" pour obtenir le même résultat:

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>

J'utilise actuellement le commentaire "# pylint: disable = no-member" pour désactiver l'avertissement, mais je préférerais ne pas le faire ... Il en va de même pour la liste blanche de la classe car je voudrais toujours que pylint signale d'autres résultats.

8
Smule

Pour répondre à votre question principale:

  1. pylintne reconnaît pas les attributs créés dynamiquement, et
  2. Enum est "spécial" dans un nombre de façons , l'un d'eux étant que les membres d'un Enum sont en fait des instances de la classe 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'>

Autrement dit, lorsque vous définissez TRUE dans votre classe GlobalEnum, Python convertit TRUE en une instance de GlobalEnum , mais pylint ne comprend pas cela, et comme il semble que GlobalEnum.TRUE se voit attribuer une valeur Tuple, pylint pense que c'est un Tuple, qui n'a pas de membre "value".

Pour répondre s'il y a une façon plus "Pythonique" d'obtenir le même résultat, je ne suis pas sûr de ce que vous essayez d'accomplir, mais il semble qu'il y ait des choses étranges que vous faites. Par exemple:

  1. __new__() obtient passé une classe comme premier argument, mais vous l'appelez "self", qui par (presque-) la convention universelle fait référence à une instance , ce qui est très déroutant à lire. Typiquement, on l'appellerait cls.

  2. Les traits de soulignement simples ("_name", "_type") Par convention sont généralement utilisés pour désigner les membres "privés", donc cela va être déroutant pour la plupart des lecteurs de les utiliser dans les signatures de fonction. Si vous souhaitez utiliser un mot réservé comme nom de paramètre, une convention courante consiste à utiliser un trait de soulignement de fin (par exemple, "type_", "exec_").

  3. Je ne sais pas ce que vous essayez d'accomplir avec votre attribut "_type", Mais pour le moment, GlobalEnum.TRUE Et GlobalEnum.FALSE Renverront une chaîne vide comme leur _type, Car str() renvoie une instance de chaîne et sans argument, la chaîne sera vide. Si vous souhaitez qu'il renvoie le type str, vous devez le définir sur str (sans les parenthèses).

  4. Je pense ce que vous essayez de faire est de créer une énumération dont les valeurs seront évaluées à True par rapport à un int ou à une chaîne que vous spécifiez dans la définition. Dans ce cas, au lieu d'une méthode equals() définie par l'utilisateur (que vous oublierez presque certainement à un moment donné), vous pouvez remplacer la méthode magique __eq__() intégrée afin que vous pouvez utiliser à la place l'opérateur == habituel:

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'

[Notez que str_value Ci-dessus n'est qu'une propriété de classe régulière, ce qui signifie qu'elle peut être définie. Pour le rendre en lecture seule, vous pouvez utiliser un décorateur de propriété sans setter.]

9
dizzy77