<h2>简短回答</h2>
<p>在Python2.x中,<code>str</code>类型保存原始字节,因此<code>dis</code>假设如果向它传递一个字符串,它将获得编译的字节码。它尝试反汇编作为字节码传递的字符串,这纯粹是因为Python字节码的实现细节成功地用于<code>i in (2,3)</code>。不过,很明显,它返回了胡言乱语。在</p>
<p>在python3.x中,<code>str</code>类型用于<em>strings</em>,<code>bytes</code>类型用于原始字节,因此<code>dis</code>可以区分编译后的字节码和字符串,并假设如果获得字符串,它将获得源代码。在</p>
<hr/>
<h2>冗长的回答</h2>
<p>这是我为解决这个问题所遵循的思考过程。在</p>
<ol>
<li><p>我在Python(3.2)上尝试过:</p>
<pre><code>>>> import dis
>>> dis.dis("i in (2,3)")
1 0 LOAD_NAME 0 (i)
3 LOAD_CONST 2 ((2, 3))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
>>> dis.dis("i in [2,3]")
1 0 LOAD_NAME 0 (i)
3 LOAD_CONST 2 ((2, 3))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
</code></pre>
<p>显然,这是有效的。</p></li>
<li><p>我在Python 2.7上尝试过:</p>
^{pr2}$
<p>啊哈!还请注意,Python3.2中生成的字节码正是您所期望的(“load<code>i</code>,load<code>(2,3)</code>,test for membership,return the result”),而在Python2.7中得到的却是胡言乱语。显然,<code>dis</code>在2.7中将字符串反编译为字节码,而在3.2中将其编译为Python。</p></li>
<li><p>我查看了<code>dis.dis</code>的源代码。以下是要点:</p>
<p>Python 2.7:</p>
<pre><code>elif isinstance(x, str):
disassemble_string(x)
</code></pre>
<p>Python 3.2:</p>
<pre><code> elif isinstance(x, (bytes, bytearray)): # Raw bytecode
_disassemble_bytes(x)
elif isinstance(x, str): # Source code
_disassemble_str(x)
</code></pre>
<p>为了好玩,让我们通过向python3中的<code>dis</code>传递相同的字节来检查这一点:</p>
<pre><code>>>> dis.dis("i in (2,3)".encode())
0 BUILD_MAP 26912
3 JUMP_FORWARD 10272 (to 10278)
6 <50>
7 <44>
8 <51>
9 <41>
</code></pre>
<p>啊哈!胡言乱语!(不过请注意,字节码随Python版本的变化而有所不同!)</p></li>
</ol>