有没有 Python 的 Case Class 等效物?就像自动生成构造函数并将其分配给字段,而不必编写样板代码。
有没有 Python 的 Case Class 等效物?就像自动生成构造函数并将其分配给字段,而不必编写样板代码。
目前(截至Python 3.7),实现这一功能的现代方法是使用数据类。例如,Scala中的case class Point(x: Int, y: Int)
在Python中变为:
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
frozen=True
是可选的,你可以省略它来得到一个可变的数据类。我包括它是为了与 Scala 的 case class 相对应。
在 Python 3.7 之前,有 collections.namedtuple
:
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
Namedtuples是不可变的,因为它们是元组。如果你想添加方法,你可以扩展namedtuple:
命名元组是不可更改的,因为它们是元组。如果您想添加方法,可以扩展命名元组:
class Point(namedtuple('Point', ['x', 'y'])):
def foo():
pass
如果你使用的是 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安装dataclass。
在macOS中: brew upgrade python3
而在scala中,以上数据类看起来像这样:
scala> final case class CustomerOrder(id: Int, customerID: String, itemName: String)
defined class CustomerOrder
dataclass
的回答都很好,但值得一提的是:
frozen=True
,那么你的数据类将无法进行哈希。所以如果你想要与Scala case类保持一致(自动定义toString
、hashcode
和equals
),那么为了获得hashcode
,你需要使用@dataclass(frozen=True)
frozen=True
,如果你的数据类包含一个不可哈希的成员(比如列表),那么这个数据类也将无法进行哈希。hash(some_data_class_instance)
将在值相等的情况下相等(且frozen=True
)frozen
数据类具有所有可哈希的成员(例如元组而不是列表),它仍然会遍历值以比较相等性,并且非常慢。