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

backticks对python解释器意味着什么:`num`,python,list-comprehension,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`

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

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.99秒对2.43秒。使用Python2.6(还没有尝试过3.0)。

Backticks是
repr()
不推荐使用的别名。不要再使用它们了,Python 3.0中删除了语法

使用backticks似乎比在2.x版中使用
repr(num)
num.\uuuu repr\uuuu()
更快。我猜这是因为需要在全局名称空间(对于
repr
)或对象名称空间(对于
\uuuu repr\uuu
)中分别进行额外的字典查找


使用
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
涉及对
\uuuuuu repr\uuuu
的属性查找,而backtick运算符在单独的操作码中实现。由于字典查找(
LOAD\u GLOBAL
/
LOAD\u ATTR
)和函数调用(
CALL\u function
)都没有开销,因此回跳速度更快

我猜Python的人认为为
repr()
单独使用一个低级操作是不值得的,同时使用
repr()
和反勾号违反了这一原则

“应该有一种——最好只有一种——显而易见的方法”


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

我的猜测是
num
没有定义方法
\uuuu str\uuu()
,因此
str()
必须对
\uu repr\uu>进行第二次查找


反勾号直接查找
\uuu repr\uu
。如果这是真的,那么使用
repr()
而不是反勾号应该会得到相同的结果。

反勾号引用通常是无用的,在Python 3中已经消失了

值得一提的是:

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

对我来说,比backtick版本稍微快一点。但担心这一点可能是过早的优化。

我想知道,如何用一些函数调用替换backticks,但这似乎是不可能的,或者是真的?使用repr()而不是backticks。Backticks是repr()come 3.0的折旧语法。实际上,我更喜欢backticks的外观,而不是调用另一个函数;它可能很难输入(在某些键盘上),很难看到它是什么,很难在Python书籍中正确打印。Etc.@kaizer.se:谢谢你指出这一点。这可能是删除反勾号的主要原因,请参阅邮件列表存档中的Guidos语句:发布此消息的最初问题是因为我无法在键盘上找到反勾号;)下面的波浪线看起来是谷歌搜索后的结果。为什么要后退一步,使用map而不是列表/迭代器理解呢?事实上,
timeit
''生成更快的结果。join(map(repr,xrange(010000))
''。join([repr(i)为xrange(010000)中的i)]
(对于
''更糟糕。join((repr(i)为xrange中的i)(0,1000000))
)。这有点令人失望;-)博宾斯的结果对我来说并不奇怪。根据经验,Python中的隐式循环比显式循环快,通常快得惊人<代码>映射
是用C实现的,使用C循环,比在虚拟机中执行的Python循环快得多。这也不奇怪,这对列表理解的声誉来说太糟糕了(在本例中命中率为30%)。但我宁愿使用清晰的速度代码,而不是火爆的速度代码,除非这真的很重要,所以这里没什么大不了的。尽管如此,map()函数并没有让我觉得不清楚,LC有时被高估了。
map
对我来说似乎非常清晰和简洁,我甚至不懂Python。在阅读了上的“另一个站点”后,我遇到了类似的问题,找到了这个页面。问得好,回答得好:)