wake-up-neo.com

Instanzattribut attributname außerhalb von __init__ definiert

Ich teile meinen Klassenkonstruktor auf, indem ich ihn mehrere Funktionen aufrufen lasse:

class Wizard:
    def __init__(self, argv):
        self.parse_arguments(argv)
        self.wave_wand() # declaration omitted

    def parse_arguments(self, argv):
        if self.has_correct_argument_count(argv):
            self.name = argv[0]
            self.magic_ability = argv[1]
        else:
            raise InvalidArgumentsException() # declaration omitted

# ... irrelevant functions omitted

Während mein Dolmetscher meinen Code glücklich ausführt, hat Pylint eine Beschwerde:

Instance attribute attribute_name defined outside __init__

Eine flüchtige Google-Suche ist derzeit erfolglos. Die gesamte Konstruktorlogik in __init__ zu behalten, scheint unorganisiert zu sein, und das Deaktivieren der Pylint-Warnung scheint auch hack-ish zu sein.

Was ist ein/der Pythonic Weg, um dieses Problem zu lösen?

109
Steven Liao

Die Idee hinter dieser Nachricht ist der Lesbarkeit zuliebe. Wir gehen davon aus, dass alle Attribute einer Instanz gefunden werden, indem die __init__-Methode gelesen wird.

Möglicherweise möchten Sie die Initialisierung jedoch auch in andere Methoden aufteilen. In diesem Fall können Sie einfach None (mit etwas Dokumentation) im __init__ Attribute zuweisen und dann die Unterinitialisierungsmethoden aufrufen.

115
sthenault

Geben Sie einfach einen Tupel von parse_arguments() zurück und packen Sie ihn nach Bedarf in __init__ in Attribute aus.

Ich würde auch empfehlen, dass Sie anstelle von exit(1) Ausnahmen verwenden. Sie erhalten Tracebacks, Ihr Code ist wiederverwendbar usw.

class Wizard:
    def __init__(self, argv):
        self.name,self.magic_ability = self.parse_arguments(argv)

    def parse_arguments(self, argv):
        assert len(argv) == 2
        return argv[0],argv[1]
23
roippi

Rufen Sie für jedes Attribut, das Sie über die Funktion festlegen möchten, die Funktion vom init aus auf. Das folgende Beispiel funktioniert für mich, um das Attribut ascii_txt ... festzulegen.

def __init__(self, raw_file=None, fingerprint=None):
    self.raw_file = raw_file
    self.ascii_txt = self.convert_resume_to_ascii()

def convert_resume_to_ascii(self):
    ret_val = self.raw_file.upper()
    return ret_val
0
Ben