Python nie gwarantuje użycia średników na końcu instrukcji. Dlaczego więc jest to (poniżej) dozwolone?
import pdb; pdb.set_trace()
Python nie gwarantuje użycia średników na końcu instrukcji. Dlaczego więc jest to (poniżej) dozwolone?
import pdb; pdb.set_trace()
Odpowiedzi:
Python nie wymaga średników do zakończenia instrukcji. Średnikiem mogą być wykorzystywane do ograniczania wypowiedzi, jeśli chcesz umieścić wiele instrukcji w tej samej linii.
Teraz, dlaczego jest to dozwolone? To prosta decyzja projektowa. Myślę, że Python nie potrzebuje tego średnika, ale ktoś pomyślał, że fajnie byłoby go mieć i dodał do języka.
timeit a = 5; a*a
timeitznaczy? a = 2; a*ajest bezużyteczny, ponieważ anadal jest 2; to musiało byća = 2; a *= a
http://docs.python.org/reference/compound_stmts.html
Instrukcje złożone składają się z co najmniej jednej „klauzuli”. Klauzula składa się z nagłówka i „zestawu”. Wszystkie nagłówki klauzul określonej instrukcji złożonej znajdują się na tym samym poziomie wcięcia. Każdy nagłówek klauzuli zaczyna się od jednoznacznie identyfikującego słowa kluczowego i kończy się dwukropkiem. Zestaw to grupa instrukcji kontrolowanych przez klauzulę. Zestaw może składać się z jednej lub więcej prostych instrukcji oddzielonych średnikami w tym samym wierszu, co nagłówek, po dwukropku nagłówka, lub może to być jedna lub więcej instrukcji z wcięciem w kolejnych wierszach . Tylko ta ostatnia forma zestawu może zawierać zagnieżdżone instrukcje złożone; poniższe jest niezgodne z prawem, głównie dlatego, że nie byłoby jasne, do której klauzuli należałaby następująca klauzula else:
if test1: if test2: print xZwróć także uwagę, że średnik wiąże się mocniej niż dwukropek w tym kontekście, więc w poniższym przykładzie wykonywane są wszystkie instrukcje print lub żadna z nich:
if x < y < z: print x; print y; print z
Zreasumowanie:
compound_stmt ::= if_stmt
| while_stmt
| for_stmt
| try_stmt
| with_stmt
| funcdef
| classdef
| decorated
suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement ::= stmt_list NEWLINE | compound_stmt
stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
if cond: stmt1; stmt2; stmt3przykładzie wszystkie lub żadne z oświadczeń nie są wykonywane ”.
Python używa znaku ;jako separatora, a nie terminatora. Możesz ich również użyć na końcu linii, co sprawia, że wyglądają jak terminator instrukcji, ale jest to dozwolone tylko dlatego, że puste instrukcje są dozwolone w Pythonie - linia zawierająca średnik na końcu to dwie instrukcje, druga jeden pusty.
stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
Po przeczytaniu odpowiedzi nadal brakuje mi jednego ważnego aspektu używania średników, być może jedynego, w którym to naprawdę robi różnicę ...
Kiedy pracujesz z interpreterem REPL (interaktywna powłoka Pythona, IDLE, ipython), wartość ostatniego wyrażenia jest drukowana na ekranie i zazwyczaj jest to zamierzone zachowanie.
Ale w niektórych przypadkach chcesz ocenić wyrażenie tylko pod kątem jego skutków ubocznych, np. Aby zobaczyć wykres wyników symulacji przez matplotlib.
W tych przypadków (prawdopodobnie) nie chcą, aby zobaczyć pełnoekranowa reprs od matplotlibobiektów, które czasami są zwracane przez wywołanie matplotlibfunkcji, a ipython przynajmniej jedną z możliwości masz jest dołączyć średnik do nadmiernie instrukcji verbose , teraz IPython widzi wiersz wejściowy jako złożony z dwóch wyrażeń, matplotlibwywołania i instrukcji null, tak że wartość wyrażenia złożonego jest Nonei nic nie jest drukowane na ekranie przez interpreter (drugą możliwością jest przypisanie , jak w _ = plot(...)ale uważam, że jest to trochę bardziej uciążliwe).
IMHO, użycie średnika w celu wyeliminowania niepożądanego wyniku w tłumaczu stało się bardziej istotne po wprowadzeniu notatnika IPyton, który umożliwia zapisywanie danych wejściowych i wyjściowych, w tym danych wyjściowych graficznych, sesji tłumacza w celu dokumentacji i ewentualnego ponownego wykorzystania .
ipython... Zredagowałem moją odpowiedź, aby odzwierciedlić Twoją uwagę.
Jak wszyscy zauważyli, do oddzielania zdań można używać średników. Nie musisz i to nie jest zwykły styl.
Jeśli chodzi o to, dlaczego jest to przydatne, niektórzy ludzie lubią umieszczać dwa lub więcej naprawdę trywialnych krótkich stwierdzeń w jednym wierszu (osobiście uważam, że zamienia to kilka trywialnych, łatwych do przejrzenia wierszy w jedną skomplikowaną linię i utrudnia dostrzeżenie, że jest to trywialne) .
Ale jest to prawie wymóg, gdy wywołujesz Python one liners z powłoki używając python -c '<some python code>'. Tutaj nie możesz używać wcięć do oddzielania instrukcji, więc jeśli twój jednolinijkowy jest naprawdę dwuwierszowy, musisz użyć średnika. A jeśli chcesz użyć innych argumentów w swoim jednolinijkowym, musisz zaimportować, sysaby uzyskać dostęp sys.argv, co wymaga osobnego importoświadczenia. na przykład
python -c "import sys; print ' '.join(sorted(sys.argv[1:]))" 5 2 3 1 4
1 2 3 4 5
pythonw powłoce: Just rozciągać swoją cytowany przez wielu linii kodu lub użyć heredoc. Jednak to zawodzi, jeśli chcesz, aby był to „jednolinijkowy”. ;)
-c
Zdaję sobie sprawę, że jako stary programista C jestem stronniczy, ale są chwile, kiedy różne konwencje Pythona utrudniają przestrzeganie pewnych zasad. Czasami uważam, że konwencja wcięć jest trochę irytująca.
Czasami bardzo przydatna jest jasność, kiedy kończy się instrukcja lub blok. Standardowy kod C często czyta coś takiego:
for(i=0; i<100; i++) {
do something here;
do another thing here;
}
continue doing things;
gdzie używasz białych znaków dla większej przejrzystości - i łatwo jest zobaczyć, gdzie kończy się pętla.
Python pozwala na zakończenie (opcjonalnym) średnikiem. Jak wspomniano powyżej, NIE oznacza to, że istnieje instrukcja do wykonania, po której następuje instrukcja „null”. I tak na przykład
print(x);
print(y);
Jest taki sam jak
print(x)
print(y)
Jeśli uważasz, że pierwsza z nich zawiera instrukcję zerową na końcu każdej linii, spróbuj - zgodnie z sugestią - zrobić to:
print(x);;
Spowoduje to zgłoszenie błędu składniowego.
Osobiście uważam, że średnik sprawia, że kod jest bardziej czytelny, gdy masz dużo zagnieżdżeń i funkcji z wieloma argumentami i / lub argumentami o długich nazwach. Tak więc, moim zdaniem, jest to o wiele jaśniejsze niż inne opcje:
if some_boolean_is_true:
call_function(
long_named_arg_1,
long_named_arg_2,
long_named_arg_3,
long_named_arg_4
);
ponieważ, dla mnie, pozwala ci wiedzieć, że ostatni „)” kończy pewien „blok”, który obejmował wiele linii.
Osobiście uważam, że jest zbyt wiele wytycznych dotyczących stylu PEP, IDE, które je egzekwują, oraz przekonania, że jest „tylko jeden sposób robienia rzeczy w Pythonie”. Jeśli wierzysz w to drugie, zobacz, jak formatować liczby: w tej chwili Python obsługuje cztery różne sposoby, aby to zrobić.
Jestem pewien, że niektórzy zagorzali mnie podpalą, ale kompilator / interpreter nie dba o to, czy argumenty mają długie czy krótkie nazwy, i - poza konwencją wcięć w Pythonie - nie przejmuje się białymi znakami. Największym problemem związanym z kodem jest udzielenie jasności drugiemu człowiekowi (a nawet sobie po miesiącach pracy), aby zrozumiał, co się dzieje, gdzie zaczyna się i kończy itd.
Średniki są częścią prawidłowej składni: 8. Instrukcje złożone (The Python Language Reference)
Cytat z „ When Pythons Attack ”
Nie kończ wszystkich swoich instrukcji średnikiem. Z technicznego punktu widzenia jest to legalne w Pythonie, ale jest całkowicie bezużyteczne, chyba że umieścisz więcej niż jedną instrukcję w jednym wierszu (np. X = 1; y = 2; z = 3).
x,y,z = 1,2,3?
x, y, z = 1, 2, 3jest wolniejszy, ponieważ pociąga za sobą niepotrzebną podróż w obie strony w budowaniu krotki, a następnie natychmiast ją desembluje. (Nawiasem mówiąc, nie sądzę, żeby @communistpancake sugerował x=1; y=2; z=3wzorzec. Myślę, że on / ona podaje jedynie przykład tego, jak średnik jest raczej separatorem niż terminatorem.)
Wiele instrukcji w jednym wierszu może zawierać średniki jako separatory. Na przykład: http://docs.python.org/reference/compound_stmts.html W twoim przypadku ułatwia to wstawienie punktu włamania do debuggera.
Ponadto, jak wspomniał Mark Lutz w książce Learning Python Book , z technicznego punktu widzenia (choć niepotrzebne i irytujące) zakończenie wszystkich wypowiedzi średnikami jest legalne .
Średniki mogą być używane w jednym wierszu, w którym znajdują się dwa lub więcej poleceń. Nie muszą być używane, ale nie są ograniczone.
Średnik (;) pozwala na umieszczanie wielu instrukcji w jednym wierszu, pod warunkiem, że żadna z instrukcji nie rozpoczyna nowego bloku kodu.
http://www.tutorialspoint.com/python/python_basic_syntax.htm
Średniki (takie jak kropki, przecinki i nawiasy) mają tendencję do wywoływania wojen religijnych. Mimo to one (lub podobny symbol) są przydatne w każdym języku programowania z różnych powodów.
Praktyczne: możliwość umieszczenia kilku krótkich poleceń, które koncepcyjnie pasują do siebie w tej samej linii. Tekst programu, który wygląda jak wąski wąż, ma odwrotny skutek do tego, co zakładają znaki nowej linii i wcięcia, czyli podkreślenie struktury.
Konceptualny: oddzielenie obaw między czystą składnią (w tym przypadku dla sekwencji poleceń) od prezentacji (np. Nowa linia), w dawnych czasach nazywane „ładnym drukowaniem”.
Obserwacja: w celu podkreślenia struktury wcięcia można w oczywisty sposób zwiększyć / zastąpić pionowymi liniami, służąc jako „wizualna linijka”, aby zobaczyć, gdzie wcięcie się zaczyna i kończy. Różne kolory (np. Zgodne z kodem kolorów dla rezystorów) mogą kompensować gromadzenie się.
Jest to dozwolone, ponieważ autorzy zdecydowali się na to zezwolić: https://docs.python.org/2/reference/simple_stmts.html
Jeśli przejdziesz do pytania, dlaczego autorzy zdecydowali się tak zrobić, myślę, że tak jest, ponieważ półkolumna jest dozwolona jako proste zakończenie instrukcji przynajmniej w następujących językach: C ++, C, C #, R, Matlab, Perl, ...
Dzięki temu łatwiej jest zacząć używać Pythona dla osób z doświadczeniem w innym języku. W takim deicisonie nie ma utraty ogólności.
Średnik („;”) jest potrzebny tylko do oddzielenia instrukcji w tym samym bloku, na przykład w przypadku następującego kodu C:
if(a>b)
{
largest=a; //here largest and count are integer variables
count+=1;
}
Można go napisać w Pythonie w jednej z dwóch form:
if a>b:
largest=a
count=count+1
Lub
if a>b: largest=a;count=count+1
W powyższym przykładzie możesz mieć dowolną liczbę instrukcji w ifbloku i można je oddzielić znakiem „;” zamiast.
Mam nadzieję, że nic nie jest tak proste, jak powyższe wyjaśnienie.
Dodając do ogromnej wiedzy, którą tutaj prezentujemy,
jest to odpowiedź związana z biblioteką matplotlib
import numpy as np
import matplotlib as plt
%matplotlib notebook
linear_data = np.array([1, 2, 3, 4, 5, 6, 7, 8])
quadratic_data = linear_data**2
plt.figure()
xvals = range(len(linear_data))
plt.barh(xvals, linear_data, height = 0.3, color='b')
plt.barh(xvals, quadratic_data, height = 0.3, left=linear_data, color='r')
Jeśli nie podasz średnika na końcu kreski (poziomej kreski), wynikiem będzie wykres + adres funkcji. Ale jeśli użyjesz średników na końcu obu linii barh, to pokazuje tylko wykres i pomija dane wyjściowe dla adresu funkcji.
Coś takiego: Porównanie