Python Dataclasses

By Alexander Hultnér

GothPy, May 17, 2018

Cetrez Logoo Created with Sketch.

About Cetrez

Cetrez is a digital innovation company.

 

We exist to accelerate our clients’ advantage in their digital journey.

Cetrez Logoo Created with Sketch.

Todays agenda

 

  • Barbecue
  • Dataclasses, Alexander Hultnér
  • Code Kata, Emily Bache
  • Drinks & mingle
Cetrez Logoo Created with Sketch.

Python Dataclasses

 

  • Coming in Python 3.7
  • Usable  in 3.6
    • pip install dataclasses
    • requires type annotations and sorted dict
  • Native alternative to attrs
  • No more misusing NamedTuples
Cetrez Logoo Created with Sketch.

Minimal dataclass

Event host

  • Very simple
  • Little verbosity
  • No boilerplate
Cetrez Logoo Created with Sketch.
@dataclass
class Host:
    name: str  # Required
    nickname: Optional[str] = None  # Optional

Meetup Class

@dataclass
class Event:
    title: str  # Required field

    # Factory default, run when created
    hosts: List[Host] = field(default_factory=list)

    # Default initiated at startup
    day: date = date.today() 

    # Executes after init 
    def __post_init__(self):
        self.hosts = [Host(**hoster) for hoster in self.hosts]


Cetrez Logoo Created with Sketch.






class EventConventionalVerbose:

    def __init__(
        self, title: str, hosts: Host = None, day: date = None
    ):
        self.title = title
        # Can't set mutable objects as default argument
        if hosts is None:
            self.hosts = []
        else:
            self.hosts = [Host(**hoster) for hoster in hosts]
        if day is None:
            self.day = date.today()
        else:
            self.day = day

    def __repr__(self):
        return f"EventConventionalVerbose"
               f"(title={self.title!r}, hosts={self.hosts!r},"
               f" day={self.day!r})"

    def __eq__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) == (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __ne__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) != (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __lt__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) < (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __le__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) <= (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __gt__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) > (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __ge__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) >= (
                other.title, other.hosts, other.day
            )
        return NotImplemented

Meetup Class

@dataclass
class Event:
    title: str  # Required field

    # Mutable objects requires a factory, 
    # otherwise they'll share state just
    # like conventional Python classes. 
    # A suggestion to change this was rejected.
    hosts: List[Host] = field(default_factory=list)

    # Initiated once at startup, in reality you'd probably
    # want a factory here as well.
    day: date = date.today() 

    # Executes after init, 
    # good for *validation* and *post processing*
    def __post_init__(self):

        # Transform host dict/mappings to instances of Host
        self.hosts = [Host(**hoster) for hoster in self.hosts]


Cetrez Logoo Created with Sketch.






class EventConventionalVerbose:

    def __init__(
        self, title: str, hosts: Host = None, day: date = None
    ):
        self.title = title
        # Can't set mutable objects as default argument
        if hosts is None:
            self.hosts = []
        else:
            self.hosts = [Host(**hoster) for hoster in hosts]
        if day is None:
            self.day = date.today()
        else:
            self.day = day

    def __repr__(self):
        return f"EventConventionalVerbose"
               f"(title={self.title!r}, hosts={self.hosts!r},"
               f" day={self.day!r})"

    def __eq__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) == (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __ne__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) != (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __lt__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) < (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __le__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) <= (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __gt__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) > (
                other.title, other.hosts, other.day
            )
        return NotImplemented

    def __ge__(self, other):
        if other.__class__ is self.__class__:
            return (self.title, self.hosts, self.day) >= (
                other.title, other.hosts, other.day
            )
        return NotImplemented

Live Demo!

 

  • Pray to the demo gods
  • Demo code at Github
Cetrez Logoo Created with Sketch.

Questions?

Cetrez

Danska vägen 8

cetrez.com

blog.cetrez.com

 

Cetrez Logoo Created with Sketch.

Python Dataclasses, with Alexander Hultnér – GothPy

By Alexander Hultnér

Python Dataclasses, with Alexander Hultnér – GothPy

GothPy Meetup, 2018-05-17 Talk about Dataclasses from Python 3.7 showcase of using the backport in Python 3.6

  • 2,339