2014-04-25 10 views
7

Dlaczego pojawia się błąd składni dla następującego kodu Pythona liniowej?Jeśli instrukcje i jeden wiersz skryptów python z wiersza polecenia

python -c 'import re; if True: print "HELLO";' 
    File "<string>", line 1 
    import re; if True: print "HELLO"; 
       ^
SyntaxError: invalid syntax 

Poniższy kod działa dobrze

python -c 'if True: print "HELLO";' 

Jak mogę zmienić jedną linię przeznaczoną do wykonywania mojego skryptu na jednej linii z linii poleceń?

+1

Brak odpowiedzi: dlaczego chcesz umieścić rzeczy w jednej linii? Jakie są korzyści, dlaczego jest lepszy niż prawdziwy scenariusz? – guettli

+0

Korzyścią jest to, że nie mam żadnych uprawnień do zapisu pliku w systemie, na którym to uruchomiłem. Ponadto, często chcę skopiować i wkleić jeden liners do przyjaciół, a to sprawia, że ​​nie muszą tworzyć plików i udzielać im tych uprawnień wykonywania. – AffluentOwl

+1

zobacz http://stackoverflow.com/questions/6167127/how-to-put-multiple-statements-in-one-line – Ashkan

Odpowiedz

6

Jedną z możliwości obejścia tego ograniczenia jest określenie polecenia z formatem $'string' z zastosowaniem sekwencji ucieczki nowej linii \n.

python -c $'import re\nif True: print "HELLO";' 

Uwaga: jest obsługiwany przez powłoki takie jak bash i zsh, ale nie jest prawidłowy POSIX sh.

Jak wspomniano przez @slaadvak, istnieje kilka innych obejścia tutaj: Executing Python multi-line statements in the one-line command-line

4

Problem nie dotyczy konkretnie instrukcji import, ponieważ zawiera ona coś przed instrukcją sterowania. To nie zadziała, albo:

[email protected]:~> python -c 'a = "1234" ; if True: print "hi"' 
    File "<string>", line 1 
    a = "1234" ; if True: print "hi" 
       ^
SyntaxError: invalid syntax 

Według odniesienia Python (https://docs.python.org/2/reference/compound_stmts.html), ';' można używać tylko do łączenia "prostych instrukcji". W tym przypadku łączysz proste oświadczenie import re, z if True:. if True nie jest prostą instrukcją, ponieważ wprowadza kontrolę przepływu, a zatem jest złożoną instrukcją. Przynajmniej tak interpretuję dokumentację.

Oto pełny tekst z odniesieniem Pythona: „klauzul”

oświadczenia złożone składają się z jednego lub większej liczby Klauzula składa się z nagłówka i Nagłówki klauzuli szczególności „pakietu”. instrukcje złożone są na tym samym poziomie wcięcia. Każdy nagłówek klauzuli rozpoczyna się od słowa kluczowego jednoznacznie identyfikującego i kończy się dwukropkiem . Pakiet to grupa zdań kontrolowanych przez klauzulę. apartament może być jeden lub więcej rozdzielone średnikami proste wypowiedzi na samej linii, co nagłówek, po dwukropku nagłówka, lub może być jeden lub więcej wcięte sprawozdania na kolejnych liniach

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)* [";"] 
+1

Wznowienie tej odpowiedzi stanowi "dlaczego" na moje pytanie. I Rynant's zapewnia obejście. – AffluentOwl

1

Ty można osadzić znaki nowej linii bezpośrednio w argumencie.

$ python -c 'import re 
> if True: 
> print "HELLO" 
> ' 
+0

Jak to zrobić? Czy jest jakaś specjalna kombinacja klawiszy? Ponieważ naciśnięcie enter powoduje wykonanie linii bez osadzania nowego znaku nowej linii. – AffluentOwl

+2

Jeśli używasz dowolnej powłoki zgodnej z POSIX, naciśnięcie klawisza Enter w środku cytowanego ciągu nie powinno wykonać polecenia (chyba że na przykład zmienisz domyślne powiązanie 'readline' dla klawisza Enter). – chepner

+0

Używam Ubuntu. Czy to może być powłoka bash zamiast powłoki zgodnej z POSIX? – AffluentOwl

1

Dlaczego otrzymuję błąd składni w następnym jeden liniowej kodu Pythona?

Python grammar może zabronić small_stmt ';' compound_stmt. -c argument prawdopodobnie jest interpretowany jako file_input:

fileinput: (NEWLINE | stmt)* ENDMARKER 
stmt: simple_stmt | compound_stmt 
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE 
small_stmt: import_stmt <in this case> 
compound_stmt: if_stmt <in this case> 

Uwaga: jest znak nowej linii na końcu simple_stmt.if_stmt nie jest small_stmt nie może śledzić innego small_stmt po ';'. Aby wprowadzić compound_stmt po small_stmt, konieczne jest wprowadzenie nowej linii.

To nie jest problem, bo bash pozwala multilinii argumentów, po prostu nie zamykają otwór apostrof aż zrobione np .:

$ python -c ' 
> import re 
> if 1: 
> print(1) 
> ' 
1 

Uwaga: > są drukowane przez samą powłokę tutaj. Nie jest wprowadzany ręcznie.

Powiązane problemy