基本上,我不认为我们都在想正确的路线。这里没有最后一行这样的东西。解释者在完全接收到表达式时引发异常。根据Python语法:http://docs.python.org/reference/grammar.html,表达式不会完全完成,直到您敲上右大括号')'。 Joran Beasley在对这个问题本身的评论中给出了相同的简单解释。
你可以做三件事做判断的这种正确性,不钻研多深成语法: -
编写代码在Python解释器:
A =(1 + 2 + 0/0 + 4 + 5)
这也引起ZeroDivionError。
写入该代码在python解释:
A =(1 + 2 + 0/0 + 4 + 5#并且,按输入
这由于表达式不完整并且不能由解释器进行解析,因此给出了无效的语法。 PS:这与问题
012中提到的代码相同
- 写入该代码在python解释:
A =(1
+0/0
5)
最后,表达式只有在您敲上右大括号时才会完成。因此,您可以继续在其中添加更多的子表达式,而不会发生任何异常。因此,从根本上讲,解释者并没有将这一切看作行号;它会等到所有表达式(包括子表达式)完成。而且,这是一个适合编程人员的编程控制流程。 PS:请原谅我对格式的回答。
新编辑: -
@海登:我认为这将是很容易通过不深入钻研语法解释的细微之处。但是,仅供您参考,我只是从URL中复制代码:http://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html
运行步骤: - 1.将代码中的代码写入temp.py文件并保存,然后导入temp在另一个文件或解释器中。这将创建temp.pyc 2.现在,将完整的代码复制并粘贴到byteCodeDetails.py中的上述URL中,然后在命令提示符下运行该文件: python byteCodeDetails.py temp.pyc。该功能show_file将在这里调用,将提供以下的输出: -
魔术03f30d0a
创建ModDate 458c2e50(星期五8月17日23时54分05秒2012)代码
argcount 0
nlocals 0堆栈大小3个标志0040码
640600640200640200151764030017640400175a000064050053 5
LOAD_CONST 6(3)
3 LOAD_CONST 2(0)
6 LOAD_CONST 2(0)
9 BINARY_DIVIDE
10 BINARY_ADD
11 LOAD_CONST 3(4)
14 BINARY_ADD
15 LOAD_CONST 4(5)
18 BINARY_ADD
19 STORE_NAME 0(一)
22 LOAD_CONST 5(无)
25 RETURN_VALUE
consts
无
名称( 'A',)
varnames()
freevars()
cellvars()
文件名 'C:\用户\的Python \ temp1.py'
名称 ''
firstlineno 5
lnotab
所以,你可以注意到: -
- 从上面提到的链接引用: 在反汇编的输出中,最左边的数字(1,2,3)是原始源文件中的行号和下一个数字(0,3,6,9 ,...)是指令的字节偏移量。同样,对于您的代码,最左边的数字只有5是行号,右边的列表示由编译器为您的代码翻译的助记符(将由解释器读取),从而指示如何表达式被形成并且它们的形成被编译代码中行号的值所取代。
- firstlineno指向5。
现在,只要在temp.py文件在你的初始代码略有变化: -
A =(1
+2
+0/0
+ 4 +
5)
现在,再次运行上述2个步骤。以下是输出: -
魔03f30d0a
创建ModDate 0f8e2e50(星期六年08月18 0时01分43秒2012)
代码
argcount 0
nlocals 0
STACKSIZE 3
标志0040
代码 640600640200640200151764030017640400175a000064050053 0 LOAD_CONST 6(3)
3 LOAD_CONST 2(0)
6 LOAD_CONST 2(0)
9 BINARY_DIVIDE
10 BINARY_ADD
11 LOAD_CONST 3(4)
14 BINARY_ADD
5 15 LOAD_CONST 4(5)
18 BINARY_ADD
19 STORE_NAME 0(一)
22 LOAD_CONST 5(无)
25 RETURN_VALUE
consts
点 无
名称( 'A',)
varnames()
freevars()
cellvars()
文件名 'C:\用户\的Python \ temp1.py'
名称 ''
firstlineno 4
lnotab 0F01
好了,现在ÿ OU可以清楚地看到两件事情: -
- 字节码是由在下一行所示的两行“代码640600640200640200151764030017640400175a000064050053”,由“4”和“5”前缀。这表明编译器已经解析了.py文件并将temp.py中的代码转换为将由解释器运行的两行代码。注意,这里第4行中的内容将被解释器执行不管表达的是完整的或不
- 的firstlineno变化4代替5
的整点的值这个冗长的讨论是,无论字节码告诉解释器哪里是一行开始的地方,以及该行应该执行的相应语句,解释器都会运行该行并在其旁边写入相应的语句。
您问题中的代码显示firstlineno为5,这就是为什么您在第5行收到错误的原因。希望这会有所帮助。
你知道,当我评论其他问题时,我想知道同样的事情。 – 2012-08-16 16:39:42
在这种情况下,它可能是其他一些非常本地化的原因(例如,.py文件和.pyc文件可能存在差异)。 – 2012-08-16 16:40:39
通常,这是最后一行。如果源文件和实际运行的代码不同步,则可能是任何行。你可以使用'dis.dis()'来查看每个字节码指令的行号。 – 2012-08-16 16:40:51