相当于Scala案例类的Python

时间:2018-07-14 18:19:53

标签: python scala

Scala的Case类是否有与Python相当的产品?就像自动生成分配给字段的构造函数而无需写出样板一样。

3 个答案:

答案 0 :(得分:13)

当前的现代方法(自python 3.7起)是使用data class。例如,Scala case class Point(x: Int, y: Int)变为:

from dataclasses import dataclass

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

frozen=True部分是可选的;您可以忽略它以获得可变数据类。我将其包括在内是为了与Scala的案例类保持一致。

在Python 3.7之前,有collections.namedtuple

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

命名元组是不可变的,因为它们是元组。如果要添加方法,则可以扩展namedtuple:

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

答案 1 :(得分:2)

如果您使用python3.7,则数据类别为@dataclass。此处的官方文档-30.6. dataclasses — Data Classes

from dataclasses import dataclass

@dataclass
class CustomerOrder(object):
  order_id: int
  customer_id: str
  item_name: str

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

确保将python3升级到python 3.7。

在macOS中:brew upgrade python3

在scala中的上述数据类看起来像

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

答案 2 :(得分:1)

关于 dataclass 的其他答案很好,但还值得一提的是:

  • 如果您不包含 frozen=True,那么您的数据类将无法进行哈希处理。因此,如果您希望与 Scala 案例类(自动定义 toStringhashcodeequals)相同,那么要获得 hashcode,您将需要 @dataclass(frozen=True)
  • 即使您确实使用了 frozen=True,如果您的数据类包含不可散列的成员(如列表),那么该数据类也不会是可散列的。
  • hash(some_data_class_instance) 将等于如果值相等(和 frozen=True
  • 根据快速的经验测试,如果您的类型是可散列的,则相等比较似乎不会更快。 Python 正在带领班级成员比较相等性。因此,即使您的 frozen 数据类具有所有可散列的成员(例如元组而不是列表),它仍然会遍历值以比较相等性并且速度非常慢。