blog.mtb-production.info

よくある経歴のPythonエンジニア

__new__ ってなに?

Python__new__ ってなんのメソッドなんだろう。

blog.mtb-production.info この記事の中で出て来た話。

正月の挨拶回りの移動時間におにぎり食べながら調べて、調べながら考えてたこと書きます。

目次

知ってること

今のところの理解は

  • __new__ は、Pythonに標準実装されてる何か
  • クラスがインスタンス化された時に読み込まれる?
  • オーバーライドした後に、 super.__new__ が実行されてるような気がする
  • フレームワークの中で出てきたり、フレームワークの拡張部分でよく使われてる。

みたいな感じ。

Pythonの公式ドキュメント読めばいいんですが、読めばいいと思いつつ読めてない状況。

ドキュメント読もう

Pythonの公式ドキュメント読みます。

これですかね

3. データモデル — Python 3.6.4 ドキュメント

読みました。

思ったこと

読んで思ったことのメモ

  • objectクラスのメソッドなんだ。ということは全てに組み込まれてるのか。
  • クラスの新しいインスタンスの作るために呼び出されるメソッドなのか。ということは、newをオーバーライドしたら、objectのnewも呼ばないとおかしくなりそう。
  • というか、やっぱりドキュメント読んでもわからん。

実際に動かしてみよう

とりあえず、 __new__ を書いてみよう。(特急電車でPCを取り出した)

class SampleClass(object):
    def __new__(cls):
        print("called my __new__ method")
        return super().__new__(cls)

SampleClass()
$ python sample__new__.py
called my __new__ method

はい。

あれ? __init__ と何が違うんだろう。

__init__ も書いてみる

class SampleClass(object):
    def __new__(cls):
        print("called my __new__ method")
        return super().__new__(cls)

    def __init__(self):
        print("called my __init__ method")

SampleClass()
SampleClass()
$ python sample__new__01.py
called my __new__ method
called my __init__ method
called my __new__ method
called my __init__ method

__new__ は初期呼び出し時にだけ呼び出されて、 __init__ は、毎回呼び出される。様な違いをイメージしたけど、違うみたい。

__init____new__ は、どう使い分けできる?

わからないけど、ドキュメントを読んでいたら、こういう風に書いてある。

new() が cls のインスタンスを返した場合、 init(self[, ...]) のようにしてインスタンスinit() が呼び出されます。このとき、 self は新たに生成されたインスタンスで、残りの引数は new() に渡された引数と同じになります。

ということは、、、、どういうことだ。。。

試行錯誤して、コードを書いてみたけど、いまいち動かなかった。

特急の到着時間が来てしまったので、ひとまず、ここで終了。

新しい疑問

  • __new____init__ って何が違うんですか
  • __new__ っていつ使うんですか。
  • Python2とPython3で __new__ は動きが違う様な?
  • Python3でメタプログラミングを調べてたら type を継承してるのが出て来たけど、これは?
  • というか、メタプログラミングってなんだろう

まとめ

とりあえず、 __new__ は、クラスのインスタンス生成をカスタマイズする時に使うというのはわかった。

ただ、 __init__ と何が違うのか、という話はよくわかってない。

なんなんだろう。そのうち時間がある時に調べたい。