重要なことを忘れてました。
CPythonとIronPythonとでは、デストラクタが実行されるタイミングが違うのでした。
CPythonでは、リファレンスカウントを利用している(さらにGCも使われているらしいけど、未確認)ので、循環する参照でも作らない限りは、del文でデストラクタを実行することが期待できます。
>>> class C(object):
def __init__(self):
print "init!"
def __del__(self):
print "del!"
>>> c = C()
init!
>>> del c
del!
>>> e = C()
init!
>>> f = e
>>> del e
>>> del f
del!
>>>
てなもんです。
が、IronPythonはリファレンスカウントを用いていないので、GCが起動される時点は神のみぞ知るです。
(クラスCの定義は同じ)
>>> c = C()
init!
>>> del c
>>>
という感じです。
ということで、IronPythonも想定した場合には、コンストラクタ・デストラクタに頼らずに、__enter__と__exit__を定義して、with文を使うことを考えた方が良いかも。
でもそれだと、CPython 2.5だけ考えれば、
with xなんたら:
hoge()
と書けば済むところを、IronPython 1.1のことも考えると、
x.__enter__()
try:
hoge()
finally:
x.__exit__(None, None, None)
みたいに書くことに。何となく情けないなあ。
(2007/11/28 追記)
記事「Python Library Reference 26.5 contextlib -- Utilities for with-statement contexts.」
http://www.python.org/doc/2.5/lib/module-contextlib.html
では、
従来の、close()で後始末する方式のオブジェクトを、with文でうまく使う方法が述べられています。2.6でwithが正式なものになるまでの間はここに書いてあるやり方を使うのが、読みやすさの点でも良いかも。
CPythonとIronPythonとでは、デストラクタが実行されるタイミングが違うのでした。
CPythonでは、リファレンスカウントを利用している(さらにGCも使われているらしいけど、未確認)ので、循環する参照でも作らない限りは、del文でデストラクタを実行することが期待できます。
>>> class C(object):
def __init__(self):
print "init!"
def __del__(self):
print "del!"
>>> c = C()
init!
>>> del c
del!
>>> e = C()
init!
>>> f = e
>>> del e
>>> del f
del!
>>>
てなもんです。
が、IronPythonはリファレンスカウントを用いていないので、GCが起動される時点は神のみぞ知るです。
(クラスCの定義は同じ)
>>> c = C()
init!
>>> del c
>>>
という感じです。
ということで、IronPythonも想定した場合には、コンストラクタ・デストラクタに頼らずに、__enter__と__exit__を定義して、with文を使うことを考えた方が良いかも。
でもそれだと、CPython 2.5だけ考えれば、
with xなんたら:
hoge()
と書けば済むところを、IronPython 1.1のことも考えると、
x.__enter__()
try:
hoge()
finally:
x.__exit__(None, None, None)
みたいに書くことに。何となく情けないなあ。
(2007/11/28 追記)
記事「Python Library Reference 26.5 contextlib -- Utilities for with-statement contexts.」
http://www.python.org/doc/2.5/lib/module-contextlib.html
では、
従来の、close()で後始末する方式のオブジェクトを、with文でうまく使う方法が述べられています。2.6でwithが正式なものになるまでの間はここに書いてあるやり方を使うのが、読みやすさの点でも良いかも。