メソッドチェーンとは
オブジェクトに対して複数のメソッドを連続して呼び出すテクニックです。
メソッドチェーンを活用することで中間の一時変数を削減でき、コードの可読性を向上させることができます。
メソッドチェーンがよく使用される例として、DjangoのORMやPandasなどのライブラリが挙げられます。
メソッドチェーンで書く場合と、一時変数を用いる場合の例
通常の書き方(一時変数を使用する場合)
result = obj.method1()
result = result.method2()
result = result.method3()
メソッドチェーンを使用する場合以下のように書けます。
result = obj.method1().method2().method3()
メソッドチェーンを使える条件
メソッドチェーンを実現するには、各メソッドが戻り値として自分自身(self)または同じ型のオブジェクトを返すように実装する必要があります。
簡単な例: メソッドチェーン対応クラス
class Example:
def __init__(self, value):
self.value = value
def add(self, num):
self.value += num
return self # 自分自身を返す
def multiply(self, num):
self.value *= num
return self # 自分自身を返す
def result(self):
return self.value
# メソッドチェーンの利用
example = Example(10)
final_value = example.add(5).multiply(2).result()
print(final_value)
# 出力結果: 30
add()
と multiply()
メソッドは、自分自身 (self
) を返すため、連続して呼び出すことができます。
実際に作成してみる
ここでは、PostgreSQLにSQLクエリを発行するためのクエリビルダーを実装します。
初めにメソッドチェーンを意識せずに作成した場合と、メソッドチェーンを意識して作成した場合を比較します。
メソッドチェーンなしのクエリビルダー
class QueryBuilder:
def __init__(self):
self._query = ""
def select(self, *columns):
cols = ", ".join(columns) if columns else "*"
self._query += f"SELECT {cols} "
def from_table(self, table_name):
self._query += f"FROM {table_name} "
def where(self, condition):
self._query += f"WHERE {condition} "
def order_by(self, column, desc=False):
direction = "DESC" if desc else "ASC"
self._query += f"ORDER BY {column} {direction} "
def build(self):
return self._query.strip() + ";"
qb = QueryBuilder()
qb.select("id", "name", "age")
qb.from_table("users")
qb.where("age > 18")
qb.order_by("name")
query = qb.build()
print(query)
# 出力結果:
# SELECT id, name, age FROM users WHERE age > 18 ORDER BY name ASC;
この場合、各メソッドがself
を返さないため、個別の呼び出しが必要です。
コードの行数が増え、中間状態のオブジェクトが残りやすくなります。
メソッドチェーンありのクエリビルダー
次に、メソッドチェーンに対応したバージョンです。
class QueryBuilder:
def __init__(self):
self._query = ""
def select(self, *columns):
cols = ", ".join(columns) if columns else "*"
self._query += f"SELECT {cols} "
return self
def from_table(self, table_name):
self._query += f"FROM {table_name} "
return self
def where(self, condition):
self._query += f"WHERE {condition} "
return self
def order_by(self, column, desc=False):
direction = "DESC" if desc else "ASC"
self._query += f"ORDER BY {column} {direction} "
return self
def build(self):
return self._query.strip() + ";"
# クエリビルダーを使ってクエリを構築
query = (QueryBuilder()
.select("id", "name", "age")
.from_table("users")
.where("age > 18")
.order_by("name")
.build())
print(query)
# 出力結果:
# SELECT id, name, age FROM users WHERE age > 18 ORDER BY name ASC;
まとめ
メソッドチェーンを意識することでよりシンプルで可読性が高いコードを書くことができます。
ぜひメソッドチェーンを活用してみてください!