5

これは基本的に、臨時職員の寿命に関する質問です。関数がオブジェクトを返すが、参照が変数に割り当てられておらず、返されたオブジェクトのメソッドを呼び出すためにのみ使用される場合、一時参照は自動的にクリアされますか?

具体的な例を挙げると、次の一連のメソッド呼び出しがあるとします。

o.method_a().method_b()

行が次のように記述されているかのように、への呼び出しが終了o.method_a()すると自動的にクリアされるによって返される一時的な参照です。method_b()

tmp = o.method_a()
try:
    tmp.method_b()
finally:
    tmp = None

編集:一般的な回答に興味があります。CPython は、参照カウントが 0 になるとすぐにオブジェクトをファイナライズします。他の Python 実装では、オブジェクトをすぐにファイナライズしない場合があります。Python 言語は C++ のようなもので、作成されたステートメントの最後で一時オブジェクトが破棄されることを保証するものなのだろうかと思います。(Python を除いて、問題は一時参照が作成されたステートメントの最後にクリアされるかどうかです。)

C++ では、同様のコードを次のように実装できます。

class B {
public:
    void method_b();
};

class A {
public:
    std::shared_ptr<B> method_a();
};



A o;
o.method_a()->method_b();

C++ 標準では、「一時オブジェクトは、作成された時点を (語彙的に) 含む完全な式を評価する最後のステップとして破棄されます。これは、その評価が例外のスローで終了した場合でも当てはまります。」この例では、std::shared_ptr<B>への呼び出しによって作成された一時オブジェクトA::method_a()が、 full-expression の評価の最後にただちに破棄されることを意味しますo.method_a()->method_b();。a の破棄とstd::shared_ptrは、共有オブジェクトへの参照をクリアすることを意味します。

4

3 に答える 3

3

はい、ガベージ コレクターは参照カウントの追跡を担当します。参照カウントがゼロになると、ガベージ コレクターはオブジェクトを削除します。これが簡単な例です。

>>> class C(object):
...     def foo(self):
...          return B()
... 
>>> class B(object):
...     def __del__(self):
...         print 'deleting %r' %self
...     def bar(self):
...         print 'I am method bar of %r' %self
... 
>>> c = C()
>>> c.foo().bar()
I am method bar of <__main__.B object at 0xa187d2c>
deleting <__main__.B object at 0xa187d2c>

補足として、他のオブジェクトから一時オブジェクトへの参照がある場合、それは削除されません。オブジェクトは、参照カウントがゼロの場合にのみガベージ コレクションされます。

についても追記deldelオブジェクトの参照カウントを削除するだけです。オブジェクトは削除されません。たとえば、 ifa = b = C()del a名前 a のみを削除し、 object の参照カウントを削除しますが、まだ参照しているC()ため、実際には削除しません。b

そうです、参照カウントは CPython の実装です。他の実装に関する限り、Python の仕様では、オブジェクトがいつ破棄されるかについて何の保証も提供していません。

これは、Python 言語リファレンスがこの問題について述べなければならないことです:

オブジェクトが明示的に破棄されることはありません。ただし、到達不能になると、ガベージ コレクションされる可能性があります。実装は、ガベージ コレクションを延期したり、完全に省略したりすることができます。まだ到達可能なオブジェクトが収集されない限り、ガベージ コレクションがどのように実装されるかは実装の品質の問題です。

于 2012-01-28T16:06:50.693 に答える
2

「クリアした」って何?「デストラクタ__del__が呼び出される」のようにクリアされるか、「関連付けられたメモリが解放される」のようにクリアされることを意味します。どちらも保証されません。たとえば、CPython 2.7.2 と PyPy 1.7.0 を比較できます [@Praveen Gollakota の例を使用]:

class C(object):
     def foo(self):
         return B()

class B(object):
    def __del__(self):
        print 'deleting %r' %self
    def bar(self):
        print 'I am method bar of %r' %self

c = C()
c.foo().bar()

print 'END OF LINE'

生産する

localhost-2:coding $ python tempref.py
I am method bar of <__main__.B object at 0x1004b7d90>
deleting <__main__.B object at 0x1004b7d90>
END OF LINE
localhost-2:coding $ pypy tempref.py
I am method bar of <__main__.B object at 0x0000000102bc4cb0>
END OF LINE
于 2012-01-28T16:14:38.277 に答える
0

良い質問。

オブジェクトは参照を持っていないため、Pythonのガベージコレクタod pythonにオブジェクトが追加されていると思います。その後、これはすぐに削除されます。

于 2012-01-28T16:10:56.717 に答える