在一个主要的Python人员的this spot in this articl处,作者指出自动字符串连接是解析器/编译器的一个特性而不是解释器,这就是你必须使用+
的原因。在运行时连接字符串。
我对此一无所知。我知道你可以与+
连接,我知道并排的两个字符串文字是自动连接的,我知道你当然不能用包含字符串的变量做到这一点但是我不知道它之间的区别是什么解析器/编译器和解释器(对于python,或者一般),我不知道它是如何与整个字符串连接事物联系起来的。
解释???
答案 0 :(得分:6)
Python是一种解释型语言(与C ++之类的语言相反,在执行之前编译为机器代码)。
现在有一个中间步骤:源(文本)文件被编译为字节码,然后Python解释器运行该字节码。
字节码编译器已经完成了逐字字符串连接(如"a" "b"
成为"ab"
)。 "a" + "b"
也是如此,因为编译器已经可以计算出文字值:
>>> import dis
>>> def s(): print "a" "b"
...
>>> dis.dis(s)
1 0 LOAD_CONST 1 ('ab')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
>>> def s(): print "ab"
...
>>> dis.dis(s)
1 0 LOAD_CONST 1 ('ab')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
>>> def s(): print "a"+"b"
...
>>> dis.dis(s)
1 0 LOAD_CONST 3 ('ab')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
但对于在编译时无法简单推断的值,解释器的工作就是连接:
>>> def s(): print "a" + chr(98)
...
>>> dis.dis(s)
1 0 LOAD_CONST 1 ('a')
3 LOAD_GLOBAL 0 (chr)
6 LOAD_CONST 2 (98)
9 CALL_FUNCTION 1
12 BINARY_ADD
13 PRINT_ITEM
14 PRINT_NEWLINE
15 LOAD_CONST 0 (None)
18 RETURN_VALUE
>>> s()
ab
答案 1 :(得分:2)
当Python代码被转换为字节代码时,并行字符串正在被合并。这只执行一次 - 每次运行脚本而不删除预编译的pyc
时,串联结果都会存在。即使没有预编译文件,连接结果也会放在字节码中,因此每次运行此代码(例如函数)时,都不需要计算连接结果。
另一方面,如果使用+
,则字节码将包含两个字符串,并且每次运行此代码时都将评估表达式。 编辑:Tim Pietzcker在his answer中并不总是如此 - 但在这种情况下,这是编译器优化的问题,而不是保证总是通过语言语义发生的行为。
请注意,因为语法是语言定义的一部分,所以编译器和解释器之间的区别在这里是无关紧要的。
答案 2 :(得分:0)
编译语言(EG:C,C ++)将人类可读的源代码转换为机器可读的机器代码。
解释语言(EG:6502上的旧微软BASIC)重新计算每次执行该步骤时需要执行的操作。
存在中间立场。像Python和Java这样的语言编译,但它们不能编译成机器代码;相反,他们编译成一个理想化的,纯软件机器的字节码。这提供了很好的可移植性和良好的速度,特别是如果与JIT(Java,Pypy,CPython 2 [56]结合使用psyco所有JIT编译字节代码)。
令人困惑的是,Java人们经常说他们的语言是编译的,并且Python没有编译,并且在硬件中实现Java运行时环境的过程中有一些讨论,但我不确定它是否已实现。
此外,gcj将Java源代码编译为机器可读的可执行文件,Cython等等也是如此。但Java和Python都主要是字节码解释。