代码之家  ›  专栏  ›  技术社区  ›  Dominic Bou-Samra

backticks对python解释器意味着什么:`num`

  •  75
  • Dominic Bou-Samra  · 技术社区  · 15 年前

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

    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() 结果比 `数字` .2.99秒对2.43秒。使用python 2.6(还没有尝试过3.0)。

    3 回复  |  直到 8 年前
        1
  •  110
  •   the Tin Man    8 年前

    backticks是不推荐使用的别名 repr() . 不再使用它们,语法在python 3.0中被删除。

    使用倒计时似乎比使用 repr(num) num.__repr__() 在2.x版本中,我想这是因为在全局命名空间中需要额外的字典查找(对于 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 涉及全局查找 再PR ,请 f2 属性查找 第二乐章 而backtick运算符是在单独的操作码中实现的。因为字典查找没有开销( LOAD_GLOBAL / LOAD_ATTR )也不适用于函数调用( CALL_FUNCTION )倒计时更快。

    我想,python人员决定为 RePrP() 不值得,而且两者都有 RePrP() 而“倒计时”违反了这一原则

    “应该有一种——最好只有一种——显而易见的方法来做到这一点。”

    所以这个特性在python 3.0中被删除了。

        2
  •  9
  •   bobince    15 年前

    在Python3中,反勾号引用通常是无效的。

    就其价值而言:

    ''.join(map(repr, xrange(10000000)))
    

    对我来说比倒勾版本快了一点。但担心这可能是过早的乐观。

        3
  •  1
  •   Aaron Digulla    15 年前

    我猜是这样的 num 没有定义方法 __str__() 如此 str() 必须进行第二次查找 __repr__ .

    backticks直接查找 _报告__ . 如果是真的,那么使用 repr() 而不是背景信号会给你同样的结果。