2017-01-06 6 views
2

IはCPythonの2.xおよび3.xに、いくつかの整数でシングルトンである、ことを理解する:従って予期参照カウントリテラル

>>> a = 256; a is 256 # or any integer from -5 to 256 
True 

>>> a = 257; a is 257 # or any other integer outside the magic range 
False 

、私は範囲の整数でsys.getrefcountを実行する場合、-5なぜなら、引数への自身参照の、

>>> sys.getrefcount(1) 
1470 

は、私はまた、より多くのsys.getrefcount 1を返しますが、あなたが想像するよりことを理解:256に、私は私のインポートされたパッケージの多くは、その整数を参照していることがわかります:

>>> sys.getrefcount(257) 
3 

なぜ3、ではない2:

>>> a = 257; sys.getrefcount(a) 
2 

私は何を得ることはありませんがこのですか?私は自分のスコープ(カウント1)に一時変数を作成している可能性があり、明らかにsys.getrefcountはそれ自身の別のリファレンスを(カウント2)追加しますが、3番目はどこから来たのですか?前の例で起こりますか?さらに重要なことは、これが起こるかもしれない他の状況があり、sys.getrefcount出力の誤解を招く可能性があるということですか?

上記のすべては、OSX上で動作するAnacondaの64ビットPython 2.7.12および3.5.1とWindows上で動作する32ビットPython 2.7.5ディストリビューションでも複製可能です。しかし、古いPythonバージョン(Windowsの32ビットPython 2.5.4)では、sys.getrefcount(257)が2を返します。これは(私にとっては)より期待されています。

+0

重要ですか?実装の詳細は、定数としてキャッシュされる不変のリテラルにつながる場合もあれば、そうでない場合もあります。 –

+0

ドキュメントから、*オブジェクトの参照カウントを返します。返されるカウントは、getrefcount()への引数として(一時的な)参照が含まれているため、一般的に予想以上のものが返されます* –

+0

@HunterMcMillen:これは3つの参照のうち2つであり、遠い –

答えて

3

ここでは、実装の詳細を実行しています。

>>> import dis 
>>> compile("sys.getrefcount(257)", '', 'single').co_consts 
(257, None) 
>>> dis.dis(compile("sys.getrefcount(257)", '', 'single')) 
    1   0 LOAD_NAME    0 (sys) 
       2 LOAD_ATTR    1 (getrefcount) 
       4 LOAD_CONST    0 (257) 
       6 CALL_FUNCTION   1 
       8 PRINT_EXPR 
      10 LOAD_CONST    1 (None) 
      12 RETURN_VALUE 

'single'は、対話型インタプリタによって使用されるモードです):コンパイラは、多くの場合、キャッシュ不変のリテラル値ことができます。

ここでは3つの参考文献を参照してください。 1つはコードオブジェクトのco_constsタプルから、1つはスタック(LOAD_CONST命令から)に、もう1つはsys.getrefcount()メソッド自体のタプルです。

+0

ありがとうございます。だから私は、他の状況(もっと重要な状況かもしれない)で、 'sys.getrefcount'が不思議なことにrefカウントを(予想よりも* more *だけ)バンプしないという信念を持っていると思いますか? – jez

+0

@jez: 'sys.getrefcount()'を信頼できます。あなたはいつでも[Pythonのデバッグビルドを作成する](https://hg.python.org/cpython/file/3.6/Misc/SpecialBuilds.txt)、そこに信じる理由があれば参照カウントをより詳細にトレースすることができますどこかのバグです。 –

関連する問題