Pythonの「なるほど!」と思えるユニークな機能④
こんにちは。ゆうせいです。
皆さんは、Pythonを使っていて不思議に思ったことはありませんか?
1 + 2は、数字を「足し算」する。"a" + "b"は、文字列を「連結」する。[1, 2] + [3, 4]は、リストを「結合」する。
同じ +(プラス)という記号なのに、相手(型)によって振る舞いがガラッと変わります。
len() 関数もそうですよね。len("abc") も len([1, 2, 3]) も、どちらも正しく長さを返してくれます。
「Pythonが賢いから?」
「+ や len() が、if文でたくさん場合分けしている?」
いいえ、違うんです!
その秘密は、「Dunder(ダンダー)メソッド」と呼ばれる、Pythonの「魔法の杖」にあります。
専門用語解説: Dunder (Double Underscore) Methods
Dunder(ダンダー)とは、Double Underscore、つまり「二重アンダースコア」のことです。
__add__ や __len__ のように、名前が __(二重アンダースコア)で始まって __ で終わる特別なメソッドたちを指します。
実は、Pythonで + や len() を使うとき、内部ではこんなことが起きています。
- あなたが
a + bと書くと…- Pythonは
aに「ねえ、__add__っていう魔法の杖(メソッド)持ってる?」と聞きに行きます。 aが__add__(b)というメソッドを持っていれば、それを実行します。- (だから、
1 + 2は(1).__add__(2)を、"a" + "b"は("a").__add__("b")を呼び出しているだけなんです!)
- Pythonは
- あなたが
len(obj)と書くと…- Pythonは
objに「__len__っていう魔法の杖、持ってる?」と聞きに行きます。 objが__len__()メソッドを持っていれば、それを実行し、その戻り値を返します。
- Pythonは
この仕組みのすごい点は、**「この魔法の杖は、私たちプログラマーも自由に作れる」**という点です!
例えば、「お財布」クラスを作ってみましょう。
class Wallet:
def __init__(self, owner, amount):
self.owner = owner
self.amount = amount
# ゆうせいのお財布と、たけしのお財布
my_wallet = Wallet("ゆうせい", 1000)
t_wallet = Wallet("たけし", 500)
この二つのお財布を + で「合算」しようとしたら、どうなるでしょう?
# new_wallet = my_wallet + t_wallet # 実行するとエラー!
# TypeError: unsupported operand type(s) for +: 'Wallet' and 'Wallet'
Pythonが「Wallet 同士を + する方法(__add__)なんて知らないよ!」と怒ってしまいました。
では、__add__ という「魔法の杖」を Wallet クラスに実装してあげましょう!
class Wallet:
def __init__(self, owner, amount):
self.owner = owner
self.amount = amount
# + 演算子(__add__)の魔法を実装!
def __add__(self, other):
# 「other」には + の右側(t_wallet)が入る
if isinstance(other, Wallet): # 相手もWalletなら
new_owner = self.owner + "と" + other.owner
new_amount = self.amount + other.amount
return Wallet(new_owner, new_amount) # 新しいWalletを返す
else:
return NotImplemented # できない、と伝える
# print()(__str__)の魔法も実装!
def __str__(self):
# print() で呼び出されたときの「見た目」
return f"お財布(持ち主: {self.owner}, 金額: {self.amount}円)"
my_wallet = Wallet("ゆうせい", 1000)
t_wallet = Wallet("たけし", 500)
# __add__ が動く!
new_wallet = my_wallet + t_wallet
# __str__ が動く!
print(new_wallet)
実行結果:
お財布(持ち主: ゆうせいとたけし, 金額: 1500円)
見てください! 私たちが作った Wallet オブジェクトが、まるで組み込みのリストや文字列のように + で合算できるようになりました!
ついでに __str__(print() での表示方法)も実装したので、print() したときの見た目もきれいになりましたね。
__lt__(< 比較)を実装すれば sort() できるようになり、__len__ を実装すれば len() できるようになります。
このように、Pythonの演算子や組み込み関数は、すべてこの「Dunderメソッド」(Pythonデータモデル)という「約束事」の上で動いているのです。
特徴3: 式の中で「代入」しちゃう!? セイウチ演算子 :=
最後は、Python 3.8から導入された、比較的新しい「魔法」です。
見た目が「:(目)」と「=(牙)」で、横倒しの「セイウチ(Walrus)」に似ていることから、「セイウチ演算子」と呼ばれています。
この := が解決するのは、プログラミングで非常によくある、この「ちょっとイラッとする」パターンです。
:= を知らない場合:
ファイルから1行ずつ読み込み、その行が空("")になるまで処理を続けたいとします。
# file は開いているとします
line = file.readline() # (1) 1回目の読み込み
while line: # (2) line に中身があるかチェック
print(line.strip())
line = file.readline() # (3) 2回目(以降)の読み込み
file.readline() という「値の取得」が、ループの「前」と「中」の2箇所に重複してしまっています。
これは美しくない(Not Pythonic)ですよね?
セイウチ演算子 := を使った場合:
while (line := file.readline()): # (1) 読み込み、代入、チェックを同時に!
print(line.strip())
たったこれだけです!
専門用語解説: セイウチ演算子 := (代入式)
=(代入文)は、「a = 10」のように、それ自体が「文」としてしか使えませんでした。
if a = 10: なんて書けませんよね?
:=(代入式)は、「式」の中で代入を行う ことができます。
while (line := file.readline()):
これは、Pythonにとって、こんな風に見えます。
- まず、
()の中のline := file.readline()を実行するぞ。 file.readline()を実行し、その結果(例えば"hello\n")をline変数に代入する。:=演算子自体の「値」は、代入された値("hello\n")になる。- 結果、
while "hello\n":と同じ意味になる。 "hello\n"は Truthy なので、ループが実行される。(lineには"hello\n"が入ったまま!)file.readline()が空文字列""を返すと、while (line := ""):となる。""は Falsy なので、whileループが終了する。
if文 でも大活躍します。
# if で計算結果を変数に保存しつつ使う
if (length := len(my_list)) > 10:
print(f"このリストは長すぎます: {length} 個")
「値を取得し、その値をチェックし、もしOKならその値を使い続けたい」という、よくある処理を、重複なく1行でエレガントに書くための、現代のPythonicな道具なんです!
まとめと今後の学習指針
いかがでしたか?
- Dunderメソッド (
__add__など): Pythonの演算子や関数の「正体」。これを実装することで、自作のオブジェクトがPythonに「ネイティブ」に組み込まれたかのように振る舞える! - セイウチ演算子 (
:=): 「代入」と「チェック」を同時に行い、ループなどの冗長なコードをスッキリさせる!
Dunderメソッドは、Pythonの「オブジェクト指向」の根幹をなす、非常に重要な概念(Pythonデータモデル)です。
セイウチ演算子は、そのPythonの哲学(可読性や効率性)を、さらに推し進めるための新しい道具です。
ここまで学んできたあなたは、もはや「Pythonの文法を知っている」レベルではなく、「Pythonがどういう思想で設計されているか」を理解し始めた、真のPythonistaと言えるでしょう。
この先には、@classmethod や @staticmethod といったデコレータの仲間たち、そしてPythonの「神の領域」とも呼ばれる「メタクラス」の世界が待っています。
ぜひ、その探究心を燃やし続けてください!
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール
- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。
最新の投稿
山崎講師2025年11月2日Pythonの「なるほど!」と思えるユニークな機能④
山崎講師2025年11月2日Pythonの「なるほど!」と思えるユニークな機能③
山崎講師2025年11月2日Pythonの「なるほど!」と思えるユニークな機能②
山崎講師2025年11月2日Pythonの「なるほど!」と思えるユニークな機能①