2015-05-06 8 views
5

Ich habe ein bisschen ein Problem mit PEP 8 getroffen.PEP 8 und Liste Verständnis

Ich benutze Liste Verständnis, die länger als 79 Zeichen lang ist. Also schreit mein Text-Editor mich an, etwas dagegen zu tun, und es ist ein Blick, den man beim Codieren sehen kann.

enter image description here

return [(i['user_id'], i['id']) for i in j['collection'] if i and i['user_id']] 

So versuche ich die Linie zu brechen, aber jetzt klagt sie brechen meine Linie für visuelle Zwecke ist.

enter image description here

return [(i['user_id'], i['id']) for i in j['collection'] 
    if i and i['user_id']] 

Was für ein Mann ist in einem solchen Gurke zu tun?

Edit: Basierend auf den Antworten, entschied ich mich für die Lesbarkeit über Liste Verständnis in diesem Fall, und jetzt macht es mehr Sinn für den Leser:

tracks = set() 

for track in json['collection']: 
    if track and track['user_id']: 
     tracks.add((track['user_id'], track['id'])) 
+4

Holen Sie sich einen vernünftigen Editor? – alexis

+0

Versuchen Sie, die Zeile vor dem zu brechen? Das ist normalerweise was ich tue. Ich denke, es ist sowieso besser lesbar. – Shashank

+2

Sei kein Sklave des Führers. [RHettinger's Vortrag] (https://www.youtube.com/watch?v=wf-BqAjZb8M) aus dieser PyCon sehr relevant. Spezifisch: nicht * Schaden * Lesbarkeit für den Zweck der Einhaltung eines Leitfadens. Sie können Ihren Editor und lokale Lint-Konfigurationen so konfigurieren, dass 100 oder 120 Zeichenzeilen möglich sind, 80 ist lächerlich. – tzaman

Antwort

6

Bei der Verwendung von Pep8 gilt der gesunde Menschenverstand. Wenn Sie eine Logikzeile nicht innerhalb von 80 Zeichen einfügen können, ist dies fast immer ein Zeichen dafür, dass diese Zeile neu geschrieben werden muss. Und es ist in diesem Fall wahr, da ich nicht einmal anfangen kann zu versuchen, zu verstehen, was diese Linie tun soll.

Aber wenn Sie es in ein viel besser lesbares Format verschieben, dann wird nicht nur die Anzahl Ihrer Zeilen steigen, sondern auch Ihre Lesbarkeit, so dass Sie Platz für richtige Variablennamen wie user statt i haben. Dies wird Ihre eigene Wartung in der Zukunft viel einfacher machen, ganz zu schweigen davon, ob jemand anderes es jemals anschauen muss.

So dieses Beispiel in tatsächlichen Code zu setzen, das ist, was ich mit ihm tun würde (mit einer netten Funktion wickelt die Probe viel leichter lesbar zu machen!):

j = {'collection': [{'id': 1, 'user_id': 1}]} 

def get_qualified_users(users): 
    qualified_users = [] 
    for user in users: 
     if user and user['user_id']: 
      qualified_users.append((user['user_id'], user['id'])) 
    return qualified_users 

print(get_qualified_users(j['collection'])) 

Sie können ganz einfach kopieren/fügen Sie es in Ihren Interpetor ein, um zu sehen, dass es funktioniert. Und mehr als das - es ist extrem einfach zu pflegen und zu folgen, mit klarem api eingekapselt in einer versiegelten Funktion.

+0

Ich habe aus diesem Grund oft Probleme mit Listenergänzungen. Viele Male bin ich zurück zum Code gegangen und habe mir für ein paar Minuten den Kopf gekratzt, um herauszufinden, was sie tun. Vor allem, wenn sie komplexer werden. –

+1

@LOLKAT warum umarmen Sie sie dann? Lass die Fesseln fallen, überarbeite den Code, mach es besser! –

+0

@LOLKAT Ich habe die Antwort mit einem Codebeispiel aktualisiert, was ich meine, über Zeit, diese Frage zu umbrechen;). –

4

, wenn Sie sich strikt an PEP8 halten wollen, dann Der hängenden Eindruck ist dein Freund.

return [ 
    (i['user_id'], i['id']) 
    for i in j['collection'] 
    if i and i['user_id']] 
1

Während ich ein Fan der Entspanntheit der strikten 80-Char-Grenze bin, und (wie erwähnt) so ist Raymond Hettinger in diesem zwingenden Vortrag von PyCon 2015, in diesem speziellen Fall könnte das sauberste Ding zu sein aufgeteilt in zwei Zeilen:

valid_things = (i for i in j['collection'] if i and i['user_id']) 
return [(i['user_id'], i['id']) for i in valid_things] 

diese Weise wird die „Filterung“ und „Auswahl“ Logik klar getrennt sind und in einer lesbaren Weise dargestellt, als sie zusammen Verklemmen.

Eine weitere Option für die funktionell geneigten:

return map(itemgetter('user_id', 'id'), valid_things) 
+1

Irgendwie hast du den schon kaum lesbaren Code sogar noch weniger lesbar gemacht. Kommt es mit einem Handbuch? –

+1

Es ist nicht weniger lesbar als das Original und könnte besser gemacht werden, wenn 'i' und' j' aussagekräftige Namen hätten, die ich nicht liefern kann, da ich keinen Kontext habe. – tzaman

+0

Ich muss dem widersprechen, denn im ursprünglichen Einzeiler ist es einfach, dem Kontext zu folgen, während man hier zuerst einige 'valid_things' erhält und dann gibt es eine Zeile, die nur erwähnt, dass sie die' valid_things' im Ende davon. Ich denke also, ich muss das von rechts nach links lesen, aber nur in der zweiten Zeile, da dies nur ein Weg ist, um zumindest lesbar zu sein. –

0

Sie müssen nur richtig die zweite Zeile einrücken:

return [(i['user_id'], i['id']) for i in j['collection'] 
     if i and i['user_id']] 

Confirmed mit PEP8 Online, aber lassen Sie mich wissen, ob es funktioniert für dich auch.

Persönlich mag ich nicht Ausdruck und Quelle zusammen, aber die Bedingung getrennt. Ich würde den Ausdruck eher deutlich sehen, nicht den Zustand. Markieren Sie, was Sie bekommen. So würde ich eine von ihnen tun:

return [(i['user_id'], i['id']) 
     for i in j['collection'] if i and i['user_id']] 

return [(i['user_id'], i['id']) 
     for i in j['collection'] 
     if i and i['user_id']] 

Klarstellung: Dies ist, wie ich indent würde/brechen. Ich habe die Variablennamen nicht berücksichtigt, da ich nur eine direkte Antwort geben und erklären wollte, was der PEP8-Fehler war und wie er behoben werden konnte, weil niemand sonst etwas getan hatte.

+0

Ja, all diese Optionen sind ebenfalls gültig. Persönlich würde ich "i" und "j" zu etwas Bedeutungsvollem machen, das die höchste Priorität hat; Darüber hinaus wählen Sie einfach einen Stil und konsistent in Ihrer Codebasis. – tzaman

+0

Es besteht zwar PEP8, aber möchten Sie wirklich, dass Ihre gesamte Codebasis so aussieht? Ich habe meine Antwort mit der Frage aktualisiert, wie ich diesen Code neu formatieren würde. Es gibt nicht nur pep8 weiter, sondern ist sogar für Laien verständlich (was ein Punkt ist), was immer ein gutes Zeichen ist. –

+0

@tzaman Danke. Ich würde wahrscheinlich auch umbenennen. Ich gebe zu, dass ich diesen Code nicht einmal angeschaut habe, abgesehen von Einrückungen. –