web-dev-qa-db-ja.com

pythonインタプリタ: `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秒かかります。

どちらも同じ結果になりますが、1つはかなり遅いです。ここで何が起こっていますか?

編集:奇妙な... repr()は_`num`_よりも少し遅い結果を与えます。 2.99秒と2.43秒。 Python 2.6(まだ3.0を試していません)を使用しています。

79

バックティックは、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には、reprf2のグローバルルックアップ、__repr__の属性ルックアップが含まれますが、バックティック演算子は別のオペコードに実装されます。辞書検索(LOAD_GLOBAL/LOAD_ATTR)や関数呼び出し(CALL_FUNCTION)のオーバーヘッドがないため、バックティックは高速です。

Python人々は、repr()に対して個別の低レベル操作を行うことは価値がないと判断し、repr()とバックティックの両方を持つことは原則に違反する

「1つ-そしてできれば1つだけ-それを行う明白な方法があるべきです」

そのため、この機能はPython 3.0で削除されました。

116
Ferdinand Beyer

バックティッククォートは一般に役に立たず、Python 3。

それが価値があるものについては、これ:

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

私のバックティックバージョンよりもわずかに高速です。しかし、これを心配するのはおそらく時期尚早な最適化です。

9
bobince

私の推測では、num__str__()メソッドを定義していないので、str()は___repr___の2回目の検索を行う必要があります。

バックティックは___repr___を直接探します。それが当てはまる場合、バックティックの代わりにrepr()を使用しても同じ結果が得られます。

1
Aaron Digulla