2017-05-19 9 views
0

refcountがどのようにPythonで動作するかを理解しようとしています。なぜオブジェクトがそのインスタンスが1つだけの場合にカウントが2になるのか説明できますか? (それがあるため、一時はGETREFCOUNTメソッドに渡されているのでしょうか?)また、なぜメンバーから呼び出されたときに呼び出されるより数が(参照カウントをぶつけ自己参照である?)されRefcount pythonオブジェクト

import sys 

class A: 
    def print_ref_count(self): 
     print sys.getrefcount(self) 

a = A() 
print sys.getrefcount(a) # prints 2 
a.print_ref_count()  # prints 4 
print sys.getrefcount(a) # prints 2 

答えて

2

暗黙的な参照の増分はどこにでもあります。 Pythonで。あなたが関数の引数としてaを渡すと、それはgetrefcount自身のdocstringノートとして、incref-EDです:

それが(一時的に)含まれているため、返されるカウントは、一般的にあなたが想像するより1高くなっていますgetrefcount()の引数としての参照。あなたがメソッドを呼び出す

二つの追加の参照は、それぞれ、以下のとおりです。

  1. メソッド内で名前selfで開催された参照
  2. それがバインドされたメソッドオブジェクトが特定行ったときに作成された暗黙的な参照あなたがa.print_ref_count(実際にそれを呼び出す前でさえ)をしたときのそのインスタンスへ。 type(a.print_ref_count)は、インスタンスとメソッド自体の両方への参照が含まれている必要があり、一時的なバインド方法、である(そして、あなたがto_print = a.print_ref_countを行うことができ、del a、およびto_printはまだaはもはやインスタンスを参照しているにもかかわらず、動作してはならない)

取得参照カウントでハングアップしてもあまり役に立ちません。これはPythonの実装の詳細です(具体的にはCPython、他のPythonインタプリタは非参照カウントガーベジコレクションを使用できます)。わかるように、名前付き変数には実際には格納されない暗黙の参照が多数作成されます。

+0

サイドノート:refカウントを1にすることは可能ですが、オブジェクトを参照カウントする目的でのみ作成する必要があります(オブジェクトは、オブジェクトに格納される不変のリテラルにすることはできません)。関数の定数、空の 'tuple'または不変のリテラルの空ではないタプルなど)。したがって、 'sys.getrefcount(A())'は 'sys.getrefcount( ''。join(( ''、 'b'、 'c')))'インターンリテラルは避けてください)、いずれも非常に役に立ちません。 – ShadowRanger

関連する問題