2012-05-03 9 views
11

Podczas szukania odpowiedzi w kodzie źródłowym pakietu (durszlak)) natknąłem się na ciąg znaków, którego nie mogę zrozumieć. Również mój PyCharm jest zaskoczony tym, że "instrukcja nie ma żadnego efektu".Jaki efekt ma instrukcja "var i do_something_with (var)" w języku Python?

Oto streszczenie kod:

... 
for path in e.paths(): 
    keyparts = [] 
    msgs = [] 
    for exc in path: 
     exc.msg and msgs.extend(exc.messages()) # <-- what is that? 
     keyname = exc._keyname() 
     keyname and keyparts.append(keyname) # <-- and that 
    errors['.'.join(keyparts)] = '; '.join(interpolate(msgs)) 
return errors 
... 

Wydaje się być bardzo pythonic i chcę go opanować!

UPD. Tak więc, jak widzę, w ogóle nie jest to pythonic - czytelność jest poszkodowana ze względu na skrót.

+1

+1 - to jest dobre pytanie, to naprawdę dziwne i nie mam pojęcia, dlaczego ktoś by to zrobił. Twierdzę, że w ogóle nie jest to Python - czytelność jest jedną z najważniejszych rzeczy w Pythonie, a jeśli spojrzeć na nią i zapytać "dlaczego to robimy", to nie jest Python. –

+0

@ Legatware Zgadzam się co do poważnego problemu z tym związanego, głównie żartowałem z pytona :) – yentsun

+0

@Lattyware: Jeśli pytasz, bo nie wiesz, jak działają 'i' i' lub ', to nie jest refleksja nad jego Pythonicness. Używanie 'i' jako strażnika jest bardzo Pythoniczne. –

Odpowiedz

15

Jeśli nazwa klucza zostanie oceniona jako Fałsz, instrukcja and zwróci false natychmiast i nie oceni drugiej części. W przeciwnym razie oceni drugą część (nie, że w tym przypadku liczy się wartość zwracana). Więc to w zasadzie równoważne:

if keyname: 
    keyparts.append(keyname) 

nie jestem pewien, że jest to bardzo pythonic jednak, ponieważ wersja po prostu zasugerował wydają się o wiele bardziej czytelny (dla mnie osobiście, przynajmniej).

+3

Uzgodnione. Przykład OP narusza "wyraźny jest lepszy niż niejawny" bez ważnego powodu. – Marcin

+0

Drugi przykład to niepoprawna składnia na python2 i python3. nie rób tego. – SingleNegationElimination

+0

Ups, dzięki, masz rację. Będę edytować – happydave

2

Ponieważ w python pierwszy wyraz w oświadczeniu and jest oceniany przed drugim i przerw tłumaczy się z oceny sprawozdania and jeżeli pierwszy wyraz jest False,

keyname and keyparts.append(keyname) 

odpowiada:

if keyname: 
    keyparts.append(keyname) 
3

i or to short-circuiting operatory logiczne; co oznacza, że ​​gdy tylko Python wie, jaka musi być odpowiedź, przestaje oceniać pozostałe klauzule.

we fragmencie pan pisał and jest używany do ochrony funkcji .extend() i .append() - przypuszczalnie autor nie chce pisać, na przykład, None na listach.

I zazwyczaj korzystać z tej funkcji w if stwierdzeń:

if name and name[0] in ('Mr', 'Mrs', 'Ms'): 
    ... 

name jest prawdopodobnie pusta lista - jeśli jest ono puste, name[0] zawiedzie z IndexError, więc pilnuj go z name and - jeśli namejest pusty, name[0] (i blok if) nie są wykonywane i błąd jest omijany.

Jest to funkcja pythoniczna w postaci bardzo.

+0

Jeśli imię ma jeden element w twoim przykładzie, masz kłopoty. nazwa [0] sprawiłaby, że przykład byłby bardziej poprawny. – happydave

+0

@happydave, dobry punkt, dzięki. W oryginalnym fragmencie 'name' zawsze miałoby co najmniej dwa elementy, gdyby istniało w ogóle, ale nie było to oczywiste, gdy zostało wyjęte z kontekstu. –

+1

@EthanFurman +1 dla łącza i wyjaśnienie przyczyny tej struktury. Podoba mi się również to, że nazywa się "pilnować" - teraz już wiem, jak go rozwiązać. W twoim przykładzie widzę więcej sensu w używaniu strażnika, ponieważ masz "jeśli".Ale oryginalny przykład 'a i b.method()' ma złą czytelność i czystą pułapkę dla nowych użytkowników (mogę sobie wyobrazić, jak dojrzali pythoniści to lubią :) – yentsun

Powiązane problemy