Cat & Code & Crimson

思索と技術が交差する場所

Tips #37:Python __slots__ 入門 ― メモリ削減と属性制限の使いどころ(Python深掘りスキル)

この Tips シリーズでは、#9 までに基本的なデータ構造、#17 までに Pythonイディオム、#30 までに Python実践スキル を紹介してきました。
今回は Python深掘りスキル の7回目として、__slots__ を取り上げます。今回も「なぜ必要か・どう役立つか」を大切にしながら進めます。

Pythonのクラスは非常に柔軟で、インスタンスに後から自由に属性を追加できます。


class Cat:
    pass

cat = Cat()
cat.name = "Chii"
cat.age = 8

これは便利ですが、実は次のような問題が潜んでいます。

  • タイポしても気づけない(cat.weigth = 4.2 もエラーにならない)
  • 大量のインスタンスを生成するとメモリ消費が増える
  • クラスがどの属性を持つのかコードから読み取りにくい

こうした問題を解決する仕組みが __slots__ です。

続きを読む

Tips #36:抽象クラス(ABC)で設計の骨格を作る(Python深掘りスキル)

この Tips シリーズでは、#9 までに基本的なデータ構造、#17 までに Pythonイディオム、#30 までに Python実践スキル を紹介してきました。
今回は Python深掘りスキル の6回目として、抽象クラス(Abstract Base Class:ABC) を取り上げます。今回も「なぜ必要か・どう役立つか」を大切にしながら進めます。

Pythonはもともと「ダックタイピング」という考え方を持つ言語です。
たとえば「area() メソッドさえ持っていれば、どんなクラスでも図形として使える」 という柔軟な仕組みです。

しかし柔軟すぎるがゆえに、こんな問題が起こることがあります。

  • area() を必ず実装してほしい」のに、実装を忘れても動いてしまう
  • 実装漏れに気づくのが、実行してエラーになった後になる
  • クラスが増えると「どのメソッドが必須か」がコードから読み取りにくくなる

こうした問題を解決するのが 抽象クラス(ABC)です。
「このメソッドは必ず実装してください」というルールを、コード自体に組み込める仕組みです。

続きを読む

Tips #35:Pythonの @property の使い方 - 安全で扱いやすい属性設計(Python深掘りスキル)

この Tips シリーズでは、#9 までに基本的なデータ構造、#17 までに Python イディオム、#30 までに Python実践スキル を紹介してきました。
今回は Python深掘りスキル の5回目として、@property を取り上げます。今回も「なぜ必要か・どう役立つか」を大切にしながら進めます。

Pythonのクラスで属性を使い始めると、こんな問題に出会います。


class Temperature:
    def __init__(self):
        self.celsius = 0

t = Temperature()
t.celsius = -999  # 絶対零度より低い値でも代入できてしまう
print(t.celsius)  # -999

属性はそのまま公開すると、どんな値でも自由に書き換えられてしまいます。
かといって、すべてをメソッドにすると呼び出しが煩雑になります。

この問題を解決するのが @property です。
「普通の属性のように書けるのに、内部では検証や計算が動く」という仕組みを作れます。

続きを読む

Tips #34:Enum で定数管理 - 可読性と安全性を高める(Python深掘りスキル)

この Tips シリーズでは、#9 までに基本的なデータ構造、#17 までに Python イディオム、#30 までに Python実践スキル を紹介してきました。
今回は Python深掘りスキル の4回目として、Enum(列挙型)を取り上げます。今回も「なぜ必要か・どう役立つか」を大切にしながら進めます。

Pythonでコードを書いていると、こんな「意味不明な値」が登場することがあります。

status = 1
direction = "lft"

この 1 は何を意味するのでしょうか? "lft" は正しいスペルでしょうか?
数字や文字列のまま管理すると、次のような問題が起きてきます。

  • コードを読んだだけでは値の意味がわからない
  • タイポ(typo)をしても実行するまでエラーに気づけない
  • 使ってよい値の範囲が決まっていても、コードで強制できない

こうした問題を解決するのが Enum(列挙型) です。

続きを読む

Tips #33:Python型ヒント - バグを未然に防ぐ typing(Python深掘りスキル)

この Tips シリーズでは、#9 までに基本的なデータ構造、#17 までに Python イディオム、#30 までに Python実践スキル を紹介してきました。
今回は、Python深掘りスキル の3回目として、型ヒント(type hints) を取り上げます。今回も「なぜ必要か・どう役立つか」を大切にしながら進めます。

Pythonは「変数の型を宣言しなくても動く」言語です。これは手軽で便利ですが、 コードが大きくなると次のような問題が起きてきます。

  • 関数に何を渡せばよいのか、コードを読んだだけではわからない
  • 間違った型を渡しても実行するまでエラーに気づけない
  • 他の人のコードを読むときに変数の中身が想像しにくい

こうした問題を解決するのが 型ヒント です。
書き方を覚えれば、コードは格段に読みやすく、安全になります。

続きを読む

Tips #32:Pythonで学ぶジェネレータ入門 - メモリ効率と遅延評価(Python深掘りスキル)

この Tips シリーズでは、#9 までに基本的なデータ構造、#17 までに Python イディオム、#30 までに Python実践スキル を紹介してきました。
今回は、Python深掘りスキル の2回目として、ジェネレータ を取り上げます。今回も「なぜ必要か・どう役立つか」を大切にしながら進めます。

Pythonでデータ処理を書いていると、こんな場面が出てきます。

  • ログファイルが数十万行あり、全部読み込むとメモリが足りない
  • APIから取得したデータを1件ずつ処理したいが、全件取得は重い
  • 条件に合うものだけを順番に取り出したい

こうした「全部一度に用意しなくていい」場面で力を発揮するのが ジェネレータ(generator)です。

続きを読む

Tips #31:Pythonで学ぶデコレータの基本 - 関数を拡張する仕組み(Python深掘りスキル)

この Tips シリーズでは、#9 までに基本的なデータ構造、#17 までに Python イディオム、#30 までに Python実践スキル を紹介してきました。
今回からは Python深掘りスキル の1回目として、デコレータ を取り上げます。

「深掘りスキル」では、動くコードが書ける から より良いコードが書ける への ステップアップを目指します。難しそうに見えますが、今回も「なぜ必要か・どう役立つか」を大切にしながら進めます。

デコレータは最初は少し不思議な構文に見えますが、「関数を関数で包む」というシンプルな構造を理解すれば、実務でも自然に使えるようになります。


1. デコレータはなぜ必要か

複数の関数に「共通の処理」を追加したいとき、デコレータなしでは同じコードを繰り返すことになります。

続きを読む