作者: 機械伯爵
日時: 2009/11/17(10:20)
 機械です。

 文法書を書いていて、ふと、__new__メソッドの挙動が私の記憶と
違っていることに気づきました。
 たしか__new__は__init__を明示的に呼ばないといけない筈だった
のに……

>>> class C:
...   def __new__(cls):
...     ins = object.__new__(cls)
...     return ins
...   def __init__(self):
...     print('init')
...
>>> c = C()
init
>>>

 明らかに、__init__が呼び出されています。
 で、どのタイミングか、を調べてみたら……

>>> class C:
...   def __new__(cls):
...     print('step1')
...     ins = object.__new__(cls)
...     print('step2')
...     return ins
...   def __init__(self):
...     print('init')
...
>>> c = C()
step1
step2
init
>>>

 どうやら、__new__メソッドが終了した時のようです。
 マニュアルにもそう書いてあるし(インスタンスを生成して
返すと__init__を実行するらしい)……でも確か前は__new__の中
でcls.__init__(ins)とか書いてたのになぁ、とか思いつつ。
 ついでに引数受け渡しの実験。

>>> class C:
...   def __new__(cls, *args):
...     return object.__new__(cls)
...   def __init__(self, *args):
...     self.args = args
...
>>> c = C(1,2,3)
>>> c.args
(1, 2, 3)
>>>

 __new__を引数なしにするとエラーが出ますが、受け取った引数を明示的に
__init__に渡さずとも、__init__には渡されるようです。
 多分ルール変更がどこかでなされたのだと思うけど……

 なかなか勉強になります、はい。

 /機械伯爵/