反引号对python解释器意味着什么:`num`

时间:2009-11-04 11:00:39

标签: python list-comprehension

我正在玩列表推导,我在另一个网站上看到了这个小片段:

return ''.join([`num` for num in xrange(loop_count)])

我花了几分钟尝试复制函数(通过输入),然后才意识到`num`位正在破坏它。

在这些字符中包含语句的内容是什么?从我所看到的它相当于str(num)。但是当我计时的时候:

return ''.join([str(num) for num in xrange(10000000)])

需要4.09秒,而:

return ''.join([`num` for num in xrange(10000000)])

需要2.43秒。

两者都给出了相同的结果,但其中一个慢得多。这是怎么回事?

编辑:奇怪...... repr()的结果比`num`略慢。 2.99s vs 2.43s。使用Python 2.6(尚未尝试过3.0)。

3 个答案:

答案 0 :(得分:113)

反引号是repr()的弃用别名。不要再使用它们了,在Python 3.0中删除了语法。

使用反引号似乎比在版本2.x中使用repr(num)num.__repr__()更快。我想这是因为全局命名空间(对于repr)或对象的命名空间(对于__repr__)分别需要额外的字典查找。


使用dis模块证明了我的假设:

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)没有开销,因此反引号更快。

我想Python人员认为对repr()进行单独的低级操作是不值得的,并且repr()和反引号都违反了原则

  

“应该有一个 - 最好只有一个 - 显而易见的方式”

因此在Python 3.0中删除了该功能。

答案 1 :(得分:9)

反引号引用通常是无用的,并且已经在Python 3中使用了。

对于它的价值,这个:

''.join(map(repr, xrange(10000000)))
对于我来说,

比反引号版本略快。但担心这可能是一个不成熟的优化。

答案 2 :(得分:1)

我的猜测是num没有定义方法__str__(),因此str()必须对__repr__进行第二次查找。

反引号直接查找__repr__。如果这是真的,那么使用repr()代替反引号应该会给你相同的结果。