作者:驴友团的新家处_273 | 来源:互联网 | 2023-02-02 00:37
如果你编译一个像这样的条件表达式,为什么呢?
def f():
if None:
print(222)
if 0:
print(333)
使用数字的分支得到优化,但那些使用的分支None
没有?例:
3 0 LOAD_CONST 0 (None)
3 POP_JUMP_IF_FALSE 14
4 6 LOAD_CONST 1 (222)
9 PRINT_ITEM
10 PRINT_NEWLINE
11 JUMP_FORWARD 0 (to 14)
5 >> 14 LOAD_CONST 0 (None)
17 RETURN_VALUE
在哪些情况下可以if 0
和if None
表现不同?
1> MSeifert..:
我的猜测:这是一个疏忽,因为None
它只是python-2.x中一个特殊的名称(或全局).
如果你看一下python-2.x中的字节码优化器代码:
switch (opcode) {
/* ... More cases ... */
/* Replace LOAD_GLOBAL/LOAD_NAME None
with LOAD_CONST None */
case LOAD_NAME:
case LOAD_GLOBAL:
j = GETARG(codestr, i);
name = PyString_AsString(PyTuple_GET_ITEM(names, j));
if (name == NULL || strcmp(name, "None") != 0)
continue;
for (j=0 ; j
您可能会注意到None
已加载LOAD_GLOBAL
或LOAD_NAME
然后替换为LOAD_CONST
.
但是:在更换它之后break
,所以它不能进入如果常量不是LOAD_CONST
用块替换块的情况.NOP
True
在python-3.x中,优化器不需要特殊情况下的名称(或全局),None
因为它总是被加载LOAD_CONST
并且字节码优化器读取:
switch (opcode) {
/* ... More cases ... */
/* Skip over LOAD_CONST trueconst
POP_JUMP_IF_FALSE xx. This improves
"while 1" performance. */
case LOAD_CONST:
CONST_STACK_PUSH_OP(i);
if (nextop != POP_JUMP_IF_FALSE ||
!ISBASICBLOCK(blocks, op_start, i + 1) ||
!PyObject_IsTrue(PyList_GET_ITEM(consts, get_arg(codestr, i))))
break;
fill_nops(codestr, op_start, nexti + 1);
CONST_STACK_POP(1);
break;
/* ... More cases ... */
}
有没有针对特殊情况LOAD_NAME
和LOAD_GLOBAL
了,所以if None
(也if False
- False
也有人提出在Python-3.X常数)将进入LOAD_CONST
的情况下,然后以一取代NOP
.