wake-up-neo.com

Python: Vermeidung von Pylint-Warnungen vor zu vielen Argumenten

Ich möchte eine große Python-Funktion in kleinere Funktionen umwandeln. Betrachten Sie beispielsweise den folgenden Codeausschnitt:

x = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9

Natürlich ist dies ein triviales Beispiel. In der Praxis ist der Code komplexer. Mein Punkt ist, dass es viele lokale Bereichsvariablen enthält, die an die extrahierte Funktion übergeben werden müssten. Dies könnte folgendermaßen aussehen:

def mysum(x1, x2, x3, x4, x5, x6, x7, x8, x9):
    x = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9
    return x

Das Problem ist, dass Pylint eine Warnung wegen zu vieler Argumente auslöst.

def mysum(d):
    x1 = d['x1']
    x2 = d['x2']
    ...
    x9 = d['x9']
    x = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9
    return x

def mybigfunction():
    ...
    d = {}
    d['x1'] = x1
    ...
    d['x9'] = x9
    x = mysum(d)

aber diese Herangehensweise ist für mich hässlich, es muss viel Code geschrieben werden, der sogar überflüssig ist.

Gibt es einen besseren Weg, dies zu tun?

35
Anonymous

Erstens, eines von Perlis 'Epigrammen :

"Wenn Sie eine Prozedur mit 10 Parametern haben, haben Sie wahrscheinlich einige verpasst."

Einige der 10 Argumente hängen vermutlich zusammen. Gruppieren Sie sie in ein Objekt und übergeben Sie das stattdessen.

Machen Sie sich ein Beispiel, weil die Frage nicht genug Informationen enthält, um direkt zu antworten:

class PersonInfo(object):
  def __init__(self, name, age, iq):
    self.name = name
    self.age = age
    self.iq = iq

Dann deine 10 Argumentfunktion:

def f(x1, x2, name, x3, iq, x4, age, x5, x6, x7):
  ...

wird:

def f(personinfo, x1, x2, x3, x4, x5, x6, x7):
  ...

und der Anrufer wechselt zu:

personinfo = PersonInfo(name, age, iq)
result = f(personinfo, x1, x2, x3, x4, x5, x6, x7)
81
user97370

Wollen Sie eine bessere Methode, um die Argumente zu übergeben, oder einfach nur, um pylint davon abzuhalten, Ihnen Schwierigkeiten zu bereiten? In letzterem Fall erinnere ich mich offenbar daran, dass Sie das Nörgeln stoppen könnten, indem Sie pylint- kontrollierende Kommentare in Ihren Code einfügen:

#pylint: disable-msg=R0913

oder:

#pylint: disable-msg=too-many-arguments

denken Sie daran, sie so schnell wie möglich wieder einzuschalten.

Meiner Meinung nach ist nichts inhärent falsch, wenn es viele Argumente und Lösungen gibt, die dafür plädieren, sie alle in einem Container-Argument zusammenzufassen. Sie lösen wirklich keine Probleme, außer dass Sie pylint davon abhalten, Sie zu nerven :-).

Wenn Sie zwanzig Argumente übergeben müssen, übergeben Sie sie. Es kann sein, dass dies erforderlich ist, weil Ihre Funktion zu viel tut und eine Neufaktorisierung dort hilfreich sein könnte. Aber es ist keine Entscheidung, die wir wirklich treffen kann, wenn wir nicht sehen, was der 'echte' Code ist.

31
paxdiablo

Sie können die maximal zulässige Anzahl von Argumenten in Pylint problemlos ändern. Öffnen Sie einfach Ihre Pylintrc-Datei (generieren Sie sie, falls Sie noch keine haben) und ändern Sie:

max-args = 5

zu:

max-args = 6 # oder ein beliebiger Wert, der zu Ihnen passt 

Aus pylint's manual

Angabe aller Optionen passend für Ihre Setup- und Codierungsstandards kann langweilig sein, so ist es möglich, Verwenden Sie eine RC-Datei, um den Standardwert anzugeben Werte. Pylint sucht nach /etc/pylintrc und ~/.pylintrc. Die --generate-rcfile Option erzeugt eine kommentierte Konfigurationsdatei gemäß der aktuelle Konfiguration auf Standard Ausgabe und beenden. Sie können andere .__ setzen. Optionen vor diesem, um sie in .__ zu verwenden. die Konfiguration oder beginnen Sie mit der Standardwerte und passen Sie die .__ manuell an. Aufbau.

20
Nadia Alramli

Sie können versuchen, die variablen Argumente von Python feature zu verwenden:

def myfunction(*args):
    for x in args:
        # Do stuff with specific argument here
12
hbw

Vielleicht könnten Sie einige der Argumente in Mitgliedsvariablen umwandeln. Wenn Sie so viel brauchen, klingt eine Klasse für mich nach einer guten Idee. 

7
Brian Rasmussen

Vereinfachen oder brechen Sie die Funktion so auf, dass keine neun Argumente erforderlich sind (oder ignorieren Sie Pylint, vermeiden Sie jedoch die Ausdrücke wie die, die Sie vorschlagen, um den Zweck eines Fusselwerkzeugs zu umgehen).

BEARBEITEN: Wenn es sich um eine temporäre Maßnahme handelt, deaktivieren Sie die Warnung für die betreffende Funktion mit einem Kommentar wie hier beschrieben: http://lists.logilab.org/pipermail/python-projects/2006-April/000664.html

Später können Sie für alle deaktivierten Warnungen grepen.

6
Dave

Kommentar zu paxdiablos Antwort - da ich nicht genug Ruf habe, um direkt dort Stellung zu nehmen: - /

Ich beziehe mich nicht gern auf die Nummer, der sybolische Name ist viel ausdrucksvoller und vermeidet, einen Kommentar hinzufügen zu müssen, der im Laufe der Zeit veraltet werden könnte.

Also würde ich lieber machen:

#pylint: disable-msg=too-many-arguments

Ich würde auch empfehlen, es nicht dort baumeln zu lassen: Es bleibt aktiv, bis die Datei endet oder deaktiviert ist, je nachdem, was zuerst eintritt.

Also besser machen:

#pylint: disable-msg=too-many-arguments
code_which_would_trigger_the_msg
#pylint: enable-msg=too-many-arguments    

Ich würde auch empfehlen, eine einzelne Warnung/einen Fehler pro Zeile zu aktivieren/deaktivieren.

4
Igor Stoppa

Ich bin auf den gleichen nörgelnden Fehler gestoßen, den ich mit einem coolen Feature zu tun hatte, das PyCharm automatisch erkennt ... fügen Sie einfach den @staticmethod-Dekorator hinzu, und dieser Fehler wird automatisch bei Verwendung der Methode entfernt

0
Ants

Python bietet einige funktionale Programmierwerkzeuge von Nice, die wahrscheinlich Ihren Anforderungen entsprechen. Check out Lambda-Funktionen und map . Sie verwenden auch Diktate, wenn es so aussieht, als wären Sie mit Listen viel besser bedient. Für das einfache Beispiel, das Sie zur Verfügung gestellt haben, versuchen Sie diese Redewendung. Beachten Sie, dass die Karte besser und schneller ist, aber möglicherweise nicht Ihren Anforderungen entspricht:

def mysum(d):
   s = 0  
   for x in d:
        s += x
   return s

def mybigfunction():
   d = (x1, x2, x3, x4, x5, x6, x7, x8, x9)
   return mysum(d)

Sie haben schon viele lokale Variablen erwähnt, aber wenn Sie mit Listen (oder Tupeln) zu tun haben, sollten Sie Listen verwenden und all diese lokalen Variablen langfristig ausfeilen.

0
easel