W Pythonie wyrażenie if można zapisać w postaci jednolinijkowca:
expr1 if cond else expr2
Jednak łatwo wpaść w pułapkę. Takie wyrażenie zadziała:
print(price-bonus) if bonus_granted else print(price)
ale już takie nie:
print(price-bonus) if bonus_granted else price = 200 print(price-bonus) if bonus_granted else pass
Ale po kolei:
price = 10
bonus = 1
bonus_granted = True
A teraz odpowiadając na pytanie. Przypomnijmy, że Pythonie można mieć statement i expressions:
- statement – coś robi i niekoniecznie cokolwiek zwraca. Przykładem statement jest pass i przypisanie wartości do zmiennych
- expression – to jest jedna lub więcej instrukcji, które coś zwracają. Przykładem expression jest np dowolny napis, dowolne obliczenie, ale też np. polecenie print (!!!!!!)
Jak sprawdzić czy coś jest expression? Prosto. Do zmiennej przypisz wynik wykonania polecenia, np.:
x = print('Hello') print("x = {}".format(x))
zwracany wynik to
Hello x = None
Widać więc, że print (chociaż głównie kojarzy nam się z robieniem czegoś – wyświetlaniem napisu) jest też expression, bo ma wartość None.
Trochę inaczej jest tu:
x = pass print("x = {}".format(x))
oto wynik:
File "C:/temp/tests.py", line 18 x = pass ^ SyntaxError: invalid syntax
Niestety – pass tylko coś robi (dokładniej rzecz biorąc „robi nic”), kompletnie nic nie zwraca, nawet None (!!!!)
Podobnie jest z przypisaniem:
x = (y=6) print("x = {}".format(x))
też błąd:
File "C:/temp/tests.py", line 21 x = (y=6) ^ SyntaxError: invalid syntax
Przypisanie się wykonuje, ale podobnie jak poprzednio kompletnie nic nie zwraca.
No i po tym wstępie mogę tłumaczyć dlaczego nie zadziałało if 🙂
Wyrażenie if zapisane w postaci jednolinijkowca musi być wyrażeniem. Pierwsze polecenie:
print(price-bonus) if bonus_granted else price = 200
nie jest wyrażeniem, bo o ile jeszcze print coś zwraca (None), o tyle druga część z przypisaniem nic nie zwraca. Stąd błąd
Podobnie będzie tu:
print(price-bonus) if bonus_granted else pass
Ale za to tutaj już tego problemu nie ma, bo tu zawsze uzyskasz wyrażenie:
print(price-bonus) if bonus_granted else print(price)
Co ciekawe, jeśli wynik tego wyrażenia chcesz zapisać w zmiennej:
x = print(price-bonus) if bonus_granted else print(price) print("x = {}".format(x))
to okaże się, że jej wartość to None:
9 x = None
Więcej na ten temat można poczytać też tu (j.ang):
Mam nadzieję, że udało mi się rozwiać wątpliwości