【问题标题】:Python equivalent of Scala case classScala 案例类的 Python 等价物
【发布时间】:2021-03-14 01:55:59
【问题描述】:

有没有 Python 等价于 Scala 的案例类?就像自动生成分配给字段的构造函数而不写出样板。

【问题讨论】:

  • “实现 Scala 的案例类”是什么意思?你在用 Python 写一个 Scala 编译器吗? “等效于 Scala 案例类”是什么意思?如果您希望 Scala 案例类的无数属性是等价的?静态类型检查? “类变量”是什么意思? Scala 没有类变量。 “不创建类实例”是什么意思?在 Scala 中,每个值都是一个对象,每个对象都是一个类的实例。

标签: python scala


【解决方案1】:

当前的现代方法(从 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

【讨论】:

  • 并且可以deeply嵌套dataclassesnamedtuples,类似于Scala的caseclass,例如像 Scala 一样可以使用 lenses?
  • @ecoe 我不知道镜头,但你可以随时发布另一个问题来找出答案。
【解决方案2】:

如果你使用python3.7,你会得到@dataclass的数据类。官方文档在这里 - 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)

确保将 python3 升级到 python 3.7,或者如果您使用 python 3.6,请从 pypi 安装数据类

在 macOS 中:brew upgrade python3

虽然 scala 中的上述数据类看起来像,

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 2016-07-05
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      相关资源
      最近更新 更多