複数の値をまとめて扱いたい時ありますよね。value object欲しいなって時
そんなとき、Scalaだとcase class
を使いますね
Case Classes | Scala Documentation
case class Human(height:Int, weight:Int)
こんな感じで、1行だけで複数の値をまとめて扱うことができます。
付随して、コンパニオンオブジェクトやメソッド群が追加されるので
applyメソッドが実装され、new
を省略できたり
scala> val taro = Human(170, 60) taro: Human = Human(170,60)
unapplyメソッドが実装され、extractorパターンによるパターンマッチができたり
scala> taro match { | case Human(h,w) => w/(h*h/10000.0) | } res42: Double = 20.761245674740483
プロパティはimmutable
scala> taro.height = 100 <console>:12: error: reassignment to val taro.height = 100
equalsメソッドが適切に実装され、同じプロパティを持つインスタンス同士を同値と判定できたり
scala> taro == Human(170,60) res43: Boolean = true
と、いろいろ便利です
で、Pythonで複数の値をまとめていい感じに扱うには?
同僚に教えてもらったnamedtuple
が便利そうです
8.3. collections — コンテナデータ型 — Python 3.6.3 ドキュメント
case classと同じく、1行でパパっと定義できて
>>> Human = namedtuple('Human', ('height', 'weight'))
サクッと、インスタンスが作れます
>>> taro = Human(height=170, weight=60) >>> taro Human(height=170, weight=60)
__str__
メソッドを定義しなくとも、オブジェクトの中身を確認できてますね
オブジェクトの属性へアクセスできるし
>>> taro.height
170
属性はimmutable
>>> taro.height = 100 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute
そしてunpacking assignmentで、値を取り出せる
>>> for h,w in [taro]: ... print(w/(h*h/10000)) ... 20.761245674740483
同じ属性を持つインスタンス同士の比較もOK
>>> taro == Human(height=170, weight=60) True
ぱっと見、クラスを定義してるように見えなくて、ナニコレ?ってなるけど、わかるととても便利なやつ