Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
前回の記事ではPythonの特殊メソッドの1つでクラス定義の中で使われる__init__()メソッドについて解説を書きました。それが下の記事です。
【Python入門】クラスの__init__()メソッドの基本についてわかりやすく解説
今回は、その__init__()メソッドと連携して機能する特殊メソッドの__new__()メソッドについてその基本的な考え方と使い方を解説します。
まず前提知識として__init__()メソッドの初歩的知識があると__new__()メソッドについても少し理解がしやすくなるので、__init__()についての解説「【Python入門】クラスの__init__()メソッドの基本についてわかりやすく解説」を読んでみてください。
Python公式ドキュメントでは次のように解説されています。
object.__new__(cls[, …])
クラス cls の新しいインスタンスを作るために呼び出されます。 __new__() は静的メソッドで (このメソッドは特別扱いされているので、明示的に静的メソッドと宣言する必要はありません)、インスタンスを生成するよう要求されているクラスを第一引数にとります。残りの引数はオブジェクトのコンストラクタの式 (クラスの呼び出し文) に渡されます。 __new()__ の戻り値は新しいオブジェクトのインスタンス (通常は cls のインスタンス) でなければなりません。
典型的な実装では、クラスの新たなインスタンスを生成するときには super().__new__(cls[, …]) に適切な引数を指定してスーパクラスの __new__() メソッドを呼び出し、新たに生成されたインスタンスに必要な変更を加えてから返します。
もし __new__() が オブジェクトの作成中に呼び出され、cls のインスタンスを返した場合には、 __init__(self[, …]) のようにして新しいインスタンスの init() が呼び出されます。このとき、 self は新たに生成されたインスタンスで、残りの引数はオブジェクトコンストラクタに渡された引数と同じになります。
__new__() が cls のインスタンスを返さない場合、インスタンスの __init__() メソッドは呼び出されません。
__new__() の主な目的は、変更不能な型 (int, str, tuple など) のサブクラスでインスタンス生成をカスタマイズすることにあります。
相変わらずよくわかりません。
そこで以下、クラスに__new__()メソッドがない場合とある場合に分けて順番に理解していきましょう。
class E:
def __init__(self, name_var, country_var):
self.name = name_var
self.country = country_var
e = E("Tom", "USA")
e.name
e.country
このコードにおける、クラスE中の__init__()メソッドは、すでに作成されているクラスEのインスタンスに対して初期設定を施すためのメソッドです。
詳しくは、記事「【Python入門】クラスの__init__()メソッドの基本についてわかりやすく解説」をご覧ください。また、Udemyのおすすめ動画講座、現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイルでもわかりやすく解説されています。
重要なのは、この__init__()メソッドが実行される前に、「すでにクラスのインスタンスが作成されている」ことです。
では、どうやってインスタンスが作成されているのでしょうか?それは、object.__new__()メソッドが自動的に実行されることでインスタンスが作られているのです。それによって作成されたインスタンスが、__init__()メソッドに渡されるという仕組みになっています。
わざわざ、クラスの中で
object.__new__(~)
と書かなくても、勝手に自動的に実行されているのです。上記公式説明の中で、
__new__() は静的メソッドで (このメソッドは特別扱いされているので、明示的に静的メソッドと宣言する必要はありません
と書かれているのはそういうことです。
このように、クラス定義の中でわざわざ__new__()メソッドを書かなくても自動的にそれが実行されてインスタンスが作られることがわかりました。
では、あえて明示的に、
def __new__(略):
と、__new__()メソッドを定義しなおした場合はどうなるのでしょうか?以下で解説します。
次のコードを見てください。
実行結果は、
2763856304320
クラスEのID: 2763856304320,
インスタンスのID: 2763864293136,
var1: Tom,
var2: USA
第1仮引数selfのID: 2763864293136
'Tom'
'USA'
となります。
このコードの処理の流れで注目すべきは、次の諸点です。
これが__new__()メソッドの基本的な考え方・使い方となります。こうしたクラスの中の特殊なメソッドについても、Udemyの動画講座の現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイルや、【完全初心者向け】絶対に挫折させないPython入門講座では動画ならではのわかりやすさがあります。
また次のような動画講座もオススメです。