Python equivalent of Scala case class

Python equivalent of Scala case class

The current, modern way to do this (as of Python 3.7) is with a data class. For example, the Scala case class Point(x: Int, y: Int) becomes:

from dataclasses import dataclass

@dataclass(frozen=True)
class Point:
    x: int
    y: int

The frozen=True part is optional; you can omit it to get a mutable data class. Ive included it for parity with Scalas case class.

Before Python 3.7, theres collections.namedtuple:

from collections import namedtuple
Point = namedtuple(Point, [x, y])

Namedtuples are immutable, as they are tuples. If you want to add methods, you can extend the namedtuple:

class Point(namedtuple(Point, [x, y])):
    def foo():
        pass

If you use python3.7 you get data classes as @dataclass. Official doc here – 30.6. dataclasses — Data Classes

from dataclasses import dataclass

@dataclass
class CustomerOrder:
  order_id: int
  customer_id: str
  item_name: str

order = CustomerOrder(1, 001, Guitar)
print(order)

Make sure to upgrade python3 to python 3.7 or if you use python 3.6 install dataclass from pypi

In macos: brew upgrade python3

While above data class in scala looks like,

scala> final case class CustomerOrder(id: Int, customerID: String, itemName: String)
defined class CustomerOrder

Python equivalent of Scala case class

The other answers about dataclass are great, but its worth also mentioning that:

  • If you dont include frozen=True, then your data class wont be hashable. So if you want parity with Scala case classes (which automatically define toString, hashcode and equals) then to get hashcode, you will need @dataclass(frozen=True)
  • even if you do use frozen=True, if your dataclass contains an unhashable member (like a list), then the dataclass wont be hashable.
  • hash(some_data_class_instance) will be equal if the values are equal (and frozen=True)
  • From a quick empirical test, equality comparisons dont appear to be any faster if your type is hashable. Python is walking the class members to compare equality. So even if your frozen dataclass has all hashable members (e.g. tuples instead of lists), it will still walk the values to compare equality and be very slow.

Leave a Reply

Your email address will not be published.