LoginSignup
40

More than 5 years have passed since last update.

Python3.7の新機能 Data Classes

Last updated at Posted at 2017-12-06

先日Pythonの新機能としてData Classesが採用されました :tada:

Data Classesとは?

PEP 557のなかで、以下のように述べられている。

Data Classes can be thought of as "mutable namedtuples with defaults". Because Data Classes use normal class definition syntax, you are free to use inheritance, metaclasses, docstrings, user-defined methods, class factories, and other Python class features.

一言で言えば、「デフォルト値があるミュータブルなnamedtuple」。

@dataclass
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

のように宣言すると、

def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0) -> None:
    self.name = name
    self.unit_price = unit_price
    self.quantity_on_hand = quantity_on_hand
def __repr__(self):
    return f'InventoryItem(name={self.name!r}, unit_price={self.unit_price!r}, quantity_on_hand={self.quantity_on_hand!r})'
def __eq__(self, other):
    if other.__class__ is self.__class__:
        return (self.name, self.unit_price, self.quantity_on_hand) == (other.name, other.unit_price, other.quantity_on_hand)
    return NotImplemented
def __ne__(self, other):
    if other.__class__ is self.__class__:
        return (self.name, self.unit_price, self.quantity_on_hand) != (other.name, other.unit_price, other.quantity_on_hand)
    return NotImplemented
def __lt__(self, other):
    if other.__class__ is self.__class__:
        return (self.name, self.unit_price, self.quantity_on_hand) < (other.name, other.unit_price, other.quantity_on_hand)
    return NotImplemented
def __le__(self, other):
    if other.__class__ is self.__class__:
        return (self.name, self.unit_price, self.quantity_on_hand) <= (other.name, other.unit_price, other.quantity_on_hand)
    return NotImplemented
def __gt__(self, other):
    if other.__class__ is self.__class__:
        return (self.name, self.unit_price, self.quantity_on_hand) > (other.name, other.unit_price, other.quantity_on_hand)
    return NotImplemented
def __ge__(self, other):
    if other.__class__ is self.__class__:
        return (self.name, self.unit_price, self.quantity_on_hand) >= (other.name, other.unit_price, other.quantity_on_hand)
    return NotImplemented

といったメソッドが自動で生成される。

namedtupleとの違い

  • namedtupleは、偶然同じ数のfieldを持つ他のnamedtupleと比較できる。
    • Data Classでは、ここでFalseを返す。
>>> Point3D(2017, 6, 2) == Date(2017, 6, 2)
True
  • namedtupleは、偶然tupleと比較できる。
    • Data Classでは、ここでFalseを返す
>>> Point2D(1,10)==(1,10)
True
  • fieldを後から追加するのが難しい
  • mutableにできない
  • デフォルト値を指定できない
  • __init____repr__に使われるfiledを制御できない
  • 継承によるfieldの結合ができない

typing.NamedTupleとの違い

  • 型アノテーションを利用できるが、結局はnamedtupleと同じ問題が残る

attrsとの違い

Python 3.7 Release Schedule

予定では2018/6/15がPython3.7のリリース日。
Data Classesは使い勝手が良さそうなので、今から楽しみですね。

PEP 537 -- Python 3.7 Release Schedule | Python.org

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40