> python -c "import os; while True: print('hello')"
> File "<string>", line 1
> import os; while True: print('hello')
> ^
> SyntaxError: invalid syntax
See the recent thread:
"for-loop on cmd-line"
The problem has nothing to do with the command line, it's caused by
trying to use a keyword 'while' somewhere other than the beginning of
the statement.
I'll ask you the same question I had: why do you bother? What's wrong
with making a separate file for the source code?
But as for solutions, first question is what OS you're running on. If
not Windows, you can probably use \n at appropriate points.
If that's not good enough, what about simply running the script instead
of a batch file?
If that's not good enough, how about merging the two languages, with a
trick like starting the python code with rem = """ followed by the
shell script?
There are many others, but we cannot choose without knowing your other
constraints.
On Fri, 12 Oct 2012 19:04:20 -0400, Etienne Robillard wrote:
> On Fri, 12 Oct 2012 15:51:19 -0700
> Herman <sorsor...@gmail.com> wrote:
>> python -c "import os; while True: print('hello')" File "<string>",
>> line 1
>> import os; while True: print('hello')
>> ^
>> SyntaxError: invalid syntax
>> --
>> http://mail.python.org/mailman/listinfo/python-list
> You get a syntax error since you didn't used tabs indents in your string
> which is normal for python AFAIK.
Incorrect. Python lets you use either spaces or tabs for indents, and in this case the SyntaxError is BEFORE the missing indent. He gets SyntaxError because you can't follow a semicolon with a statement that begins a block. It's the `while` that causes the error, not the lack of indent. Here's an example with `if` and an indented block that also fails:
[steve@ando ~]$ python -c "pass; pass"
[steve@ando ~]$ python -c "pass; if True: pass"
File "<string>", line 1
pass; if True: pass
^
SyntaxError: invalid syntax
Solution: don't use semi-colons, use newlines.
In this example, I use `Ctrl-Q ENTER` to insert a literal newline in the string, which shows as ^M. Note that you *cannot* just type ^ M (caret M), that won't work, it must be an actual control character.
I was just trying to do in a shell to quickly monitor a file. Imagine
instead of printing hello, it is "os.system("cat somefile")", etc.
Look like it works if i press an enter after the "import xxx". Thanks.
On Fri, Oct 12, 2012 at 5:29 PM, Dave Angel <d...@davea.name> wrote:
> On 10/12/2012 06:51 PM, Herman wrote:
>> python -c "import os; while True: print('hello')"
>> File "<string>", line 1
>> import os; while True: print('hello')
>> ^
>> SyntaxError: invalid syntax
> See the recent thread:
> "for-loop on cmd-line"
> The problem has nothing to do with the command line, it's caused by
> trying to use a keyword 'while' somewhere other than the beginning of
> the statement.
> I'll ask you the same question I had: why do you bother? What's wrong
> with making a separate file for the source code?
> But as for solutions, first question is what OS you're running on. If
> not Windows, you can probably use \n at appropriate points.
> If that's not good enough, what about simply running the script instead
> of a batch file?
> If that's not good enough, how about merging the two languages, with a
> trick like starting the python code with rem = """ followed by the
> shell script?
> There are many others, but we cannot choose without knowing your other
> constraints.
In article <CANOe_mi+VEW6T0ec-kcohOuxN7O2A8V6QbbZrzQrYVZi+b7...@mail.gmail.com>,
Herman <sorsor...@gmail.com> wrote:
> I was just trying to do in a shell to quickly monitor a file. Imagine
> instead of printing hello, it is "os.system("cat somefile")", etc.
> Look like it works if i press an enter after the "import xxx". Thanks.
If you are using a POSIX-compatible shell, the canonical approach for use cases like this is to use a "here document", for example:
python - <<EOF
import os
while True:
print('hello')
EOF
The "-" tells the Python interpreter to read from stdin. The shell supplies the lines between the <<EOF and the matching EOF as stdin.
On Sat, Oct 13, 2012 at 12:32:41AM +0000, Steven D'Aprano wrote:
> He gets SyntaxError because you can't follow a semicolon with a
> statement that begins a block.
Can someone provide a link on where to find this type of information?
I was just hunting through “The Python Language Reference” and could
not find anything explicit. The only thing I found is
<thb...@students.uni-mainz.de> wrote:
> On Sat, Oct 13, 2012 at 12:32:41AM +0000, Steven D'Aprano wrote:
>> He gets SyntaxError because you can't follow a semicolon with a
>> statement that begins a block.
> Can someone provide a link on where to find this type of information?
> I was just hunting through “The Python Language Reference” and could
> not find anything explicit. The only thing I found is
> “Several simple statements may occur on a single line separated by
> semicolons.”
> Anyways, this does not explicitly say “You shall not put a compound
> statement after a simple statement separated by a semicolon.”, right?
It's more that Python treats simple and compound statements as
completely separate beasts. You can combine simple statements on one
line, but compound statements mustn't be.
In my opinion, this is a major wart in Python syntax. You can argue
all you like about how it reduces code clarity to put these sorts of
things together, but that's a job for a style guide, NOT a language
requirement. Most code won't put an assignment followed by an
if/while/for, but when I'm working interactively, I often want to
recall an entire statement to edit and reuse, complete with its
initialization - something like (contrived example):
>>> a=collections.defaultdict(int)
>>> for x in open("RilvierRex.txt"): a[x]+=1
Then I keep doing stuff, keep doing stuff, and then come back to this
pair of lines. Since they're two lines, I have to recall them as two
separate entities, rather than as an initializer and the code that
uses it. Logically, they go together. Logically, they're on par with a
list comprehension, which initializes, loops, and assigns, all as a
single statement. But syntactically, they're two statements that have
to go on separate lines.
To force that sort of thing to be a single recallable statement, I can
do stupid tricks like:
>>> if True:
a=collections.defaultdict(int)
for x in open("RilvierRex.txt"): a[x]+=1
but that only works in IDLE, not in command-line interactive Python.
Note, by the way, that it's fine to put the statement _inside_ the for
on the same line. It's even legal to have multiple such statements:
>>> for x in (1,2,3): print(x); print(x);
1
1
2
2
3
3
If there's any ambiguity, it would surely be that, and not the simple
statement being first.
Okay, rant over. I'll go back to being nice now. :)
<joshua.landau...@gmail.com> wrote:
> This here isn't a flaw in Python, though. It's a flaw in the command-line
> interpreter. By putting it all on one line, you are effectively saying:
> "group these". Which is the same as an "if True:" block, and some things
> like Reinteract even supply a grouping block like "build".
> That said, because some shells suck it would be nice if:
>> python -c "a=1\nif a:print(a)"
> worked (just for -c).
Yes, that'd be nice. But it still leaves the big question of why
Python requires \n to separate one statement from another. It IS a
flaw in Python that it requires one specific statement separator in
this instance, even though it'll accept two in another instance.
Here's a side challenge. In any shell you like, start with this
failing statement, and then fix it without retyping anything:
sikorsky@sikorsky:~$ python -c "a=1; if a: print(a)"
File "<string>", line 1
a=1; if a: print(a)
^
SyntaxError: invalid syntax
In bash, I was unable to insert a newline into the quoted string. My
only option was to backspace everything after the point where I wanted
the newline, then hit enter, then retype the if. I'm curious to know
if that's simply because I didn't think of (some bash feature), or
alternatively, if there's another shell that would have made this
easy.
Back to the main point. In C-like languages, the newline is nothing
special. (ECMAScript allows the omission of semicolons at end of line
in many cases, but many style guides recommend using them anyway.) You
can, if you so desire, put all your code into a single line. It's then
up to the project's style guide to decide how things should be laid
out. For instance, this is multiple statements in PHP, but I see it as
one logical action:
$bar=array(); for ($foo as $k=>$v) $bar[$k]="<p>".$v."</p>";
It's one statement in Python:
bar = ["<p>"+x+"</p>" for x in foo]
It's one statement in Pike:
array bar = map(foo,lambda(string x) {return "<p>"+x+"</p>";});
So it should be allowed to be put on one line. And in languages whose
syntax derives from C, you almost certainly can. (I can't think of any
counter-examples, though that certainly doesn't prove they don't
exist.) But the same thing is forced onto two lines in Python, and not
for syntactic reasons - at least, not that I can see. Perhaps someone
can enlighten me.
Is there any fundamental reason that the syntax couldn't be expanded
to permit "statement; statement" for any two given statements?
Chris Angelico writes:
> Here's a side challenge. In any shell you like, start with this
> failing statement, and then fix it without retyping anything:
> sikorsky@sikorsky:~$ python -c "a=1; if a: print(a)"
> File "<string>", line 1
> a=1; if a: print(a)
> ^
> SyntaxError: invalid syntax
> In bash, I was unable to insert a newline into the quoted string. My
> only option was to backspace everything after the point where I
> wanted the newline, then hit enter, then retype the if. I'm curious
> to know if that's simply because I didn't think of (some bash
> feature), or alternatively, if there's another shell that would have
> made this easy.
<joshua.landau...@gmail.com> wrote:
> Because Python uses indentation, what would "if A: print(1); if B: print(2)"
> even do? It has to fail, because we have to assume consistent indentation
> for ";"s*. With "\n" as I proposed, you still have to indent: it is just a
> method to bypass lame shells [it would become "if A: print(1)\nif B:
> print(2)"].
The semicolon separates statements, but doesn't change nesting levels.
The if statement increases the nesting level, which demands a
corresponding indentation increase if you go onto a new line; the
statement you describe is illegal because the 'if' isn't allowed to
not be at the beginning of the line, but it's unambiguous.
Of course, since Python lacks a non-whitespace way of indicating the
end of an if block, there's no way to put your "if A" and "if B" onto
the same line as peers. But that's a consequence of a design decision,
and one that can't easily be changed. Every language has warts like
that; eschewing variable declarations prevents infinite nesting of
scopes, but demanding variable declarations makes interactive work
harder. To paraphrase the Pirate King: Always follow the dictates of
your conscience, and accept the consequences.
<joshua.landau...@gmail.com> wrote:
> The fact that your proposal can't allow "a=[]\nfor x in range(10):
> a.append(x**a[-2])\nprint(a)" makes it somewhat an incomplete suggestion,
> and code like:
>> while True: while True: break; break
> is just confusing.
Agreed. However, I don't think there's going to be _any_ perfect
solution for delimiting blocks, short of "from __future__ import
braces".
> I don't want to sound closed, but the options I'm really open to are:
> a) It does a limited set of things that make a those things nicer, á la "@"
> b) It does almost everything, minus some carefully-chosen things deemed to
> quirky, á la current newlines (which don't allow "if a: if b: pass")
> c) It does everything that would be possible
> Your example falls nicely between a and b, which I do not find particularly
> helpful. Mine attempts a by only applying to "python -c", but would be c if
> it didn't. I find the syntax to horrible for general code, which is why I
> didn't suggest that.
Your idea is an extension to the -c parameter that would technically
work, but be fairly hard to manage in anything other than the trivial
case. My idea is an extension to general syntax that would work in all
cases where you aren't trying to put a statement after the end of what
would be an indented block. Both have their limitations, but both
would be - as far as I can see - backward compatible.