Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Fundamentally, I dont think we all are thinking on the right lines. There is no such thing as the last line here. The exception is raised by the interpreter when it receives an expression fully. According to the Python grammar: <a href="http://docs.python.org/reference/grammar.html" rel="nofollow">http://docs.python.org/reference/grammar.html</a>, the expression is not fully complete until you hit a closing brace ')'. A brief explanation for the same was given by Joran Beasley in the comments against the question itself. </p> <p>You can do 3 things do judge the correctness of this, without delving much deep into the grammar:-</p> <ol> <li><p>Write this code in the python interpreter: </p> <blockquote> <p>a=(1+2+0/0+4+5)</p> </blockquote></li> </ol> <p>This also raises ZeroDivionError.</p> <ol> <li><p>Write this code in the python interpreter:</p> <blockquote> <p>a=(1+2+0/0+4+5 # And, press enter</p> </blockquote></li> </ol> <p>This gives you invalid syntax since the expression is not complete and can not be parsed by the interpreter PS: This is the same as the code mentioned in the question</p> <ol> <li>Write this code in the python interpreter:</li> </ol> <blockquote> <p>a = (1<br> +2<br> +0/0<br> +4<br> +5)<br></p> </blockquote> <p>Eventually, the expression does not complete until you hit the closing brace. Hence, you can continue to add on more sub-expressions inside it without getting any exception. Thus, fundamentally, the interpreter does not see this all as line numbers; it waits until the all the expressions (including the sub-expressions) have completed. And, it is a proper programming control flow for the interpeter.</p> <p>PS: Forgive my formatting of the answer.</p> <p>New edit:-</p> <p>@ Hayden: I thought it would be easy to explain the subtleties by not delving too deep into the grammar. But, for your reference, I am just copying the code from the URL: <a href="http://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html" rel="nofollow">http://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html</a></p> <p>Steps to run:- 1. Write your code asked in the question in a temp.py file and save it, then, import temp in another file or in the interpreter. This will create temp.pyc 2. Now, copy and paste the full code in the above mentioned URL in byteCodeDetails.py and run the file in command prompt as: python byteCodeDetails.py temp.pyc. The function show_file will be called here and will give the following output:-</p> <blockquote> <p>magic 03f30d0a<br> moddate 458c2e50 (Fri Aug 17 23:54:05 2012) code<br> argcount 0 <br> nlocals 0 stacksize 3 flags 0040 code<br> 640600640200640200151764030017640400175a000064050053 5<br> 0<br> LOAD_CONST 6 (3)<br> 3 LOAD_CONST 2 (0)<br> 6 LOAD_CONST 2 (0)<br> 9 BINARY_DIVIDE<br> 10 BINARY_ADD<br> 11 LOAD_CONST 3 (4)<br> 14 BINARY_ADD<br> 15 LOAD_CONST 4 (5)<br> 18 BINARY_ADD<br> 19 STORE_NAME 0 (a)<br> 22 LOAD_CONST 5 (None)<br> 25 RETURN_VALUE <br> consts<br> 1<br> 2<br> 0<br> 4<br> 5<br> None<br> 3 <br> names ('a',) <br> varnames () <br> freevars () <br> cellvars () <br> filename 'C:\Users\Python\temp1.py'<br> <br> name '' <br> firstlineno 5 <br> lnotab<br></p> </blockquote> <hr> <p>So, as you can notice that:-</p> <ol> <li>Quoting from the link mentioned above: <em>In the disassembled output, the left-most numbers (1, 2, 3) are the line numbers in the original source file and the next numbers (0, 3, 6, 9, ...) are the byte offsets of the instruction.</em> Similarly, for your code, the left-most number is only 5 which is the line number, and the columns to the right represent the mnemonics (to be read by the interpreter) translated by the compiler for your code., thus indicating how expressions are formed and their formation is overtaken by the value of the line numbers in the compiled code.</li> <li><strong>firstlineno points to 5.</strong><br></li> </ol> <p>Now, just make a slight change in your initial code in the temp.py file:-</p> <blockquote> <p>a = (1<br> +2<br> +0/0<br> +4<b>+</b><br> 5)<br></p> </blockquote> <p>Now, Run through the above 2 steps once again. The following is the output:-</p> <blockquote> <p>magic 03f30d0a<br> moddate 0f8e2e50 (Sat Aug 18 00:01:43 2012)<br> code<br> argcount 0<br> nlocals 0<br> stacksize 3<br><br> flags 0040<br> code 640600640200640200151764030017640400175a000064050053<br> 4<br> 0 LOAD_CONST 6 (3)<br> 3 LOAD_CONST 2 (0)<br> 6 LOAD_CONST 2 (0)<br> 9 BINARY_DIVIDE<br> 10 BINARY_ADD<br> 11 LOAD_CONST 3 (4)<br> 14 BINARY_ADD<br></p> <p>5 15 LOAD_CONST 4 (5)<br> 18 BINARY_ADD<br> 19 STORE_NAME 0 (a)<br> 22 LOAD_CONST 5 (None)<br> 25 RETURN_VALUE<br> consts<br> 1<br> 2<br> 0<br> 4<br> 5<br> None<br> 3<br> names ('a',)<br> varnames ()<br> freevars ()<br> cellvars ()<br> filename 'C:\Users\Python\temp1.py'<br> name ''<br> firstlineno 4<br><br> lnotab 0f01<br></p> </blockquote> <p>Well, now you can clearly see 2 things:-</p> <ol> <li>The byte code is composed of 2 lines shown in the next line to 'code 640600640200640200151764030017640400175a000064050053', prefixed by '4' and '5'. This shows that the compiler has parsed the .py file and converted the code in temp.py into 2 lines of code which will be run by the interpreter. <strong>Note that here the contents of line 4 will be executed by the interpreter no matter the expression is complete or not</strong> <br> </li> <li>The value of <strong>firstlineno changes to 4 instead of 5</strong></li> </ol> <p>The whole point of this lengthy discussion is that wherever the byte code indicates to the interpreter that this is where a line starts and the corresponding statements which should be executed for this line, then, the interpreter just runs that line and the corresponding statements written next to it.</p> <p>The code in your question shows firstlineno as 5, that is why you receive an error in line 5. Hopefully, this helps now.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload