反引号对python解释器意味着什么:`num`
我在玩弄列表parsing,并在另一个网站上看到这个小片段:
return ''.join([`num` for num in xrange(loop_count)])
我花了几分钟的时间试图复制函数(通过键入),然后才实现了`num`
位的分解。
在这些angular色中包含一个陈述是什么呢? 从我所能看到的是str(num)的等价物。 但是当我计时时:
return ''.join([str(num) for num in xrange(10000000)])
它需要4.09s,而:
return ''.join([`num` for num in xrange(10000000)])
需要2.43s。
两者都给出了相同的结果,但一个是慢很多。 这里发生了什么?
编辑:奇怪… repr()
给出比`num`
稍慢的结果。 2.99s vs 2.43s。 使用Python 2.6(尚未尝试3.0)。
反引号是repr()
别名。 不要再使用它们,Python 3.0中的语法被删除了。
使用反引号似乎比在版本2.x中使用repr(num)
或num.__repr__()
更快。 我想这是因为在全局命名空间(for repr
)或对象的命名空间(for __repr__
)中需要额外的字典查找。
使用dis
模块certificate了我的假设:
def f1(a): return repr(a) def f2(a): return a.__repr__() def f3(a): return `a`
拆解节目:
>>> import dis >>> dis.dis(f1) 3 0 LOAD_GLOBAL 0 (repr) 3 LOAD_FAST 0 (a) 6 CALL_FUNCTION 1 9 RETURN_VALUE >>> dis.dis(f2) 6 0 LOAD_FAST 0 (a) 3 LOAD_ATTR 0 (__repr__) 6 CALL_FUNCTION 0 9 RETURN_VALUE >>> dis.dis(f3) 9 0 LOAD_FAST 0 (a) 3 UNARY_CONVERT 4 RETURN_VALUE
f1
涉及repr
的全局查找, f2
是__repr__
的属性查找,而反引号操作符是在单独的操作码中实现的。 由于没有字典查找( LOAD_GLOBAL
/ LOAD_ATTR
)和函数调用( CALL_FUNCTION
)的CALL_FUNCTION
,所以反引号更快。
我想Python的人们认为repr()
有一个单独的低级操作是不值得的, repr()
和反引号都违反了原理
“应该有一个 – 最好只有一个 – 明显的做法”
所以这个特性在Python 3.0中被删除了。
反引号通常是无用的,并在Python 3中消失了。
为了什么是值得的,这个:
''.join(map(repr, xrange(10000000)))
比我的反向版本稍微快一点。 但担心这可能是一个不成熟的优化。
我的猜测是, num
没有定义方法__str__()
,所以str()
必须对__repr__
进行第二次查找。
反引号直接查找__repr__
。 如果这是真的,那么使用repr()
而不是反引号应该给你相同的结果。