SlideShare a Scribd company logo
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Tech Lead en Qnective AG
Encantador de serpientes desde v2.2
Trabajo en remoto desde 2016
Incapaz de soportarun invierno de
verdad desde2016
Apenas sé hablar español técnico
Gran amante de las listas
Como esta
Python
Venga!
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
p1 = Point(0, 0)
print(f'{p1}: x={p1.x}, y={p1.y}')
p2 = Point(x=0, y=0)
print(f'{p1} == {p2} -> {p1 == p2}’)
Point(x=0, y=0): x=0, y=0
Point(x=0, y=0) == Point(x=0, y=0) -> True
El dato estructurado
De tuplas a clases
Añadiendo funcionalidad a una clase
Dataclass
Casosmás simples
Comparabilidad
Hashabilidad
Campos
Valores por defecto
Herencia
__slots__
Funciones de apoyo
Proyectos de terceros
Alternativas
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
El dato estructurado
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
red = 255, 0, 0
orange = (255, 165, 0)
green = tuple(0, 255, 0)
>>> orange[0]
255
>>> r, g, b = orange
>>> g
165
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
red = list((255, 0, 0))
orange = [255, 165, 0]
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
red = dict(red=255, green=0, blue=0)
orange = {'red': 255,
'green': 165,
'blue': 0}
>>> orange[‘blue’]
0
( )
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from collections import namedtuple
Colour = namedtuple(
'Colour', 'red green blue')
red = Colour(255, 0, 0)
orange = Colour(red=255,
green=165,
blue=0)
>>> orange.red
255
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from typing import NamedTuple
class Colour(NamedTuple):
red: int
green: int
blue: int = 0 # default!
red = Colour(255, 0)
orange = Colour(red=255, green=165)
>>> red.red
255
>>> orange.blue
0
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from types import SimpleNamespace
red = SimpleNamespace(red=255, green=0, blue=0)
>>> red.red
255
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
class Colour:
def __init__(self, red, green, blue=0):
self.red = red
self.green = green
self.blue = blue
red = Colour(255, 0)
orange = Colour(red=255, green=165)
>>> red.red
255
>>> orange.blue
0
>>> print(red)
<__main__.Colour object at 0x0000019119B09358>
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def __repr__(self):
return (
f"{self.__class__.__name__}("
f"red={self.red}, green={self.green}, "
f"blue={self.blue})")
>>> print(red)
Colour(red=255, green=0, blue=0)
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
class Colour:
def __init__(self, red, green, blue=0):
self.red = red
self.green = green
self.blue = blue
def __repr__(self):
return (f"{self.__class__.__name__}("
f"red={self.red}, green={self.green}, "
f"blue={self.blue})")
>>> red1 = Colour(255, 0, 0)
>>> red2 = Colour(255, 0, 0)
>>> red1 == red2
False
>>> red1 == red1
True
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def __eq__(self, other):
if other.__class__ is not self.__class__:
return NotImplemented
return (self.red, self.green, self.blue) == (
other.red, other.green, other.blue)
>>> red1 = Colour(255, 0, 0)
>>> red2 = Colour(255, 0, 0)
>>> red1 == red2
True
>>> red1 is red2
False
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
class Colour:
def __init__(self, red, green, blue=0):
self.red = red
self.green = green
self.blue = blue
def __repr__(self):
return (f"{self.__class__.__name__}("
f"red={self.red}, green={self.green}, "
f"blue={self.blue})")
def __eq__(self, other):
if other.__class__ is not self.__class__:
return NotImplemented
return (self.red, self.green, self.blue) == (
other.red, other.green, other.blue)
>>> list(sorted([orange, red]))
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: '<' not supported between instances of
'Colour' and 'Colour'
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def __lt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) < (
other.red, other.green, other.blue)
return NotImplemented
...
>>> list(sorted([orange, red]))
[Colour(red=255, green=0, blue=0), Colour(red=255,
green=165, blue=0)]
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
class Colour:
def __init__(self, red, green, blue=0):
self.red = red
self.green = green
self.blue = blue
def __repr__(self):
return (f"{self.__class__.__name__}("
f"red={self.red}, green={self.green}, "
f"blue={self.blue})")
def __eq__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) == (
other.red, other.green, other.blue)
return NotImplemented
def __ge__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) >= (
other.red, other.green, other.blue)
return NotImplemented
def __gt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) > (
other.red, other.green, other.blue)
return NotImplemented
def __le__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) <= (
other.red, other.green, other.blue)
return NotImplemented
def __lt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) < (
other.red, other.green, other.blue)
return NotImplemented
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def __delattr__(self, name):
raise TypeError(f'cannot delete field {name}')
def __setattr__(self, name, value):
raise TypeError(f'cannot assign to field {name}’)
>>> red = Colour(255, 0, 0)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 4, in __init__
File "<input>", line 48, in __setattr__
TypeError: cannot assign to field red
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def __init__(self, red, green, blue=0):
object.__setattr__(self, "red", red)
object.__setattr__(self, "green", green)
object.__setattr__(self, "blue", blue)
>>> red = Colour(255, 0, 0)
>>> red.blue = 1
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 23, in __setattr__
TypeError: cannot assign to field blue
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def __hash__(self):
return hash((self.red, self.green, self.blue))
>>> hash(red)
1738572376461218158
>> set([red])
{Colour(red=255, green=0, blue=0)}
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
class Colour:
def __init__(self, red, green, blue=0):
object.__setattr__(self, "red", red)
object.__setattr__(self, "green", green)
object.__setattr__(self, "blue", blue)
def __repr__(self):
return (f"{self.__class__.__name__}("
f"red={self.red}, green={self.green}, "
f"blue={self.blue})")
def __eq__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) == (
other.red, other.green, other.blue)
return NotImplemented
def __ge__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) >= (
other.red, other.green, other.blue)
return NotImplemented
def __gt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) > (
other.red, other.green, other.blue)
return NotImplemented
def __le__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) <= (
other.red, other.green, other.blue)
return NotImplemented
def __lt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) < (
other.red, other.green, other.blue)
return NotImplemented
def __delattr__(self, name):
raise TypeError(f'cannot delete field {name}')
def __setattr__(self, name, value):
raise TypeError(f'cannot assign to field {name}')
def __hash__(self):
return hash((self.red, self.green, self.blue))
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Añade.
Otro.
Campo.
El módulo dataclasses
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from dataclasses import dataclass
@dataclass
class Colour:
red: int
green: int
blue: int
orange = Colour(red=255, green=165, blue=0)
red = Colour(255, 0, 0)
>>> red
Colour(red=255, green=0, blue=0)
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
# Python 3.5
from typing import Optional
def fun(width: float,
name: Optional[str]=None) -> None:
pass
# Python 3.6
temperature: float
temperature = 'cold'
class Measurement:
speed: float
__annotations__
from dataclasses import dataclass
@dataclass
class Colour:
red: int
green: int
blue: int
orange = Colour(red=255, green=165, blue=0)
red = Colour(255, 0, 0)
red2 = Colour(255, 0, 0)
>>> red == red2
True
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from dataclasses import dataclass
@dataclass
class Colour:
red: int
green: int
blue: int
red = Colour(255, 0, 0)
>>> red.red = 240
>>> red
Colour(red=240, green=0, blue=0)
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from dataclasses import dataclass
@dataclass
class Colour:
red: int
green: int
blue: int
>>> list(sorted([orange, red]))
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: '<' not supported between instances of
'Colour' and 'Colour'
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
@dataclass(order=True)
class Colour:
red: int
green: int
blue: int
>>> list(sorted([orange, red]))
[Colour(red=255, green=0, blue=0),
Colour(red=255, green=165, blue=0)]
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def dataclass(_cls=None, *, order=False):
def wrap(cls):
return _process_class(cls, order)
# See if we're being called as @dataclass
# or @dataclass().
if _cls is None:
# We're called with parens.
return wrap
# We're called as @dataclass without parens.
return wrap(_cls)
@dataclass(order=True)
class Colour:
red: int
green: int
blue: int
>>> hash(red)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: unhashable type: 'Colour'
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
@dataclass(order=True, frozen=True)
class Colour:
red: int
green: int
blue: int
>>> hash(red)
1738572376461218158
>> set([red])
{Colour(red=255, green=0, blue=0)}
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
@dataclass(order=True, frozen=True)
class Colour:
red: int
green: int
blue: int
>>> red.red = 240
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<string>", line 3, in __setattr__
dataclasses.FrozenInstanceError: cannot assign
to field 'red'
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Dataclass
@dataclass(order=True, frozen=True)
class Colour:
red: int
green: int
blue: int
Claseartesanal
• class Colour:
def __init__(self, red, green, blue=0):
object.__setattr__(self, "red", red)
object.__setattr__(self, "green", green)
object.__setattr__(self, "blue", blue)
def __repr__(self):
return (f"{self.__class__.__name__}("
f"red={self.red}, green={self.green}, "
f"blue={self.blue})")
def __eq__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) == (
other.red, other.green, other.blue)
return NotImplemented
def __ge__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) >= (
other.red, other.green, other.blue)
return NotImplemented
def __gt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) > (
other.red, other.green, other.blue)
return NotImplemented
def __le__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) <= (
other.red, other.green, other.blue)
return NotImplemented
def __lt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) < (
other.red, other.green, other.blue)
return NotImplemented
def __delattr__(self, name):
raise TypeError(f'cannot delete field {name}')
def __setattr__(self, name, value):
raise TypeError(f'cannot assign to field {name}')
def __hash__(self):
return hash((self.red, self.green, self.blue))
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
def dataclass(
_cls=None, *,
init=True,
repr=True,
eq=True,
order=False,
unsafe_hash=False,
frozen=False):
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Los campos de una dataclass
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
@dataclass
class Colour:
red: int
green: int
blue: int = 0
orange = Colour(red=255, green=165)
red = Colour(255, 0)
>>> red
Colour(red=255, green=0, blue=0)
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from typing import List
@dataclass
class Employee:
name: str
surname: str
children: List[str] = []
john = Employee('John', 'Green')
hank = Employee('Hank', 'Green’)
john.children.append('Henry')
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Traceback (most recent call last):
File "<input>", line 3, in <module>
File "dataclasses.py", line 966, in dataclass
return wrap(_cls)
File "dataclasses.py", line 958, in wrap
return _process_class(cls, init, repr, eq, order,
unsafe_hash, frozen)
File "dataclasses.py", line 809, in _process_class
for name, type in cls_annotations.items()]
File "dataclasses.py", line 809, in <listcomp>
for name, type in cls_annotations.items()]
File "dataclasses.py", line 702, in _get_field
raise ValueError(f'mutable default
{type(f.default)} for field '
ValueError: mutable default <class 'list'> for field
children is not allowed: use default_factory
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from dataclasses import dataclass, field
from typing import List
@dataclass
class Employee:
name: str
surname: str
children: List[str] = field(default_factory=list)
john = Employee('John', 'Green')
hank = Employee('Hank', 'Green')
john.children.append('Henry')
john.children.append('Alice’)
>>> hank.children
[]
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
__annotations__
dataclasses.Field
__dataclass_fields__
def field(*,
default=MISSING,
default_factory=MISSING,
init=True,
repr=True,
hash=None,
compare=True,
metadata=None):
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from typing import ClassVar
@dataclass
class Colour:
MAX: ClassVar[int] = 255
red: int
green: int
blue: int = 0
red = Colour(255, 0)
orange = Colour(255, 165)
>>> red.MAX
255
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from dataclasses import dataclass, field, InitVar
@dataclass
class Address:
protocol: InitVar[str]
host: InitVar[str]
url: str = field(init=False)
def __post_init__(self, protocol, host):
self.url = f'{protocol}://{host}/'
addr = Address('http', ‘example.com’)
>>> addr
Address(url='http://google.com/')
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
@dataclass
class Point1d:
x: float
@dataclass
class Point2d(Point1d):
y: float
@dataclass
class Point3d(Point2d):
z: float
p1 = Point1d(11.1)
p2 = Point2d(22.2, 33.3)
p3 = Point3d(44.4, 55.5, 66.6)
>>> p1, p2, p3
(Point1d(x=11.1), Point2d(x=22.2, y=33.3), Point3d(x=44.4, y=55.5,
z=66.6))
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
@dataclass
class Colour:
__slots__ = (
'red’,
'green’,
'blue')
red: int
green: int
blue: int
>>> red.check = True
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'Colour' object has no attribute
'check'
Rapidez de acceso
Restricción de creación de campos
Ahorro de espacio
¡Sin valores por defecto!
Funciones de apoyo
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
fields Lista los campos guardados. Funciona con instancias y
clases.
asdict Convierte un objeto en diccionario de forma recursiva
astuple Convierte un objeto en tupla de forma recursiva
replace Crea una copia (no profunda) de un objeto con algunos
campos cambiados de valor.
is_dataclass Comprueba si un objeto o clase es una dataclass
make_dataclass Crea una nueva clase con dataclass
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
fields Lista los campos guardados. Funciona con instancias y
clases.
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
>>> dataclasses.fields(red)
(Field(name='red’,...
Field(name='green',type=<class
'int'>,default=<dataclasses._MISSING_TYPE object at
0x0000028B13380208>,default_factory=<dataclasses._MISSI
NG_TYPE object at
0x0000028B13380208>,init=True,repr=True,hash=None,compa
re=True,metadata=mappingproxy({}),_field_type=_FIELD),
Field(name='blue’,...))
asdict Convierte un objeto en diccionario de forma recursiva
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
>>> dataclasses.asdict(red)
{'red': 255, 'green': 0, 'blue': 0}
astuple Convierte un objeto en tupla de forma recursiva
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
>>> dataclasses.astuple(red)
(255, 0, 0)
replace Crea una copia (no profunda) de un objeto con algunos
campos cambiados de valor.
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
>>> red2 = dataclasses.replace(red, blue=12)
>>> red2
Colour(red=255, green=0, blue=12)
is_dataclass Comprueba si un objeto o clase es una dataclass
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
>>> dataclasses.is_dataclass(red)
True
>>> dataclasses.is_dataclass(Colour)
True
>>> dataclasses.is_dataclass([])
False
make_dataclass Crea una nueva clase con dataclass
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
from dataclasses import make_dataclass
Colour = make_dataclass('Colour',
fields=[('red', int), ('green', int),
('blue', int)])
red = Colour(255, 0, 0)
orange = Colour(255, 165, 0)
Proyectos relacionados
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
dataslots Decorador with_slots, añade slots a una
dataclass.
dataclass-factory Crea instancias de dataclasses a partir de
diccionarios. Inverso a asdict.
strictclasses Decorador que hace que se comprueben tipos
en asignación.
dataclassinspector Intenta mostrar el equivalente al código
generado por una dataclass. Intenta.
fistro Genera instancias de dataclasses con datos
para pruebas. Fixtures.
dataclasses-jsonschema Crea JSON schema a partir de una dataclass.
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
La alternativa
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
import attr
@attr.s
class Colour:
red: int = attr.ib()
green: int = attr.ib()
blue: int = attr.ib()
red = Colour(255, 0, 0)
>>> red
Colour(red=255, green=0, blue=0)
Funciona desde Python 2.7
Soporta __slots__
Validadores
Convertidores
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
La recta final
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
El dato estructurado
De tuplas a clases
Añadiendo funcionalidad a una clase
Dataclass
Casosmás simples
Comparabilidad
Hashabilidad
Campos
Valores por defecto
Herencia
__slots__
Funciones de apoyo
Proyectos de terceros
Alternativas
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Dataclass
@dataclass(order=True, frozen=True)
class Colour:
red: int
green: int
blue: int
Claseartesanal
• class Colour:
def __init__(self, red, green, blue=0):
object.__setattr__(self, "red", red)
object.__setattr__(self, "green", green)
object.__setattr__(self, "blue", blue)
def __repr__(self):
return (f"{self.__class__.__name__}("
f"red={self.red}, green={self.green}, "
f"blue={self.blue})")
def __eq__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) == (
other.red, other.green, other.blue)
return NotImplemented
def __ge__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) >= (
other.red, other.green, other.blue)
return NotImplemented
def __gt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) > (
other.red, other.green, other.blue)
return NotImplemented
def __le__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) <= (
other.red, other.green, other.blue)
return NotImplemented
def __lt__(self, other):
if other.__class__ is self.__class__:
return (self.red, self.green, self.blue) < (
other.red, other.green, other.blue)
return NotImplemented
def __delattr__(self, name):
raise TypeError(f'cannot delete field {name}')
def __setattr__(self, name, value):
raise TypeError(f'cannot assign to field {name}')
def __hash__(self):
return hash((self.red, self.green, self.blue))
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Añade.
Otro.
Campo.
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
Todd Ehlers en Flickr
Philippe_ en Flickr
Leo Hidalgo en Flickr
Antonio Trogu en Flickr
Bruce Baugh en Flickr
VivaAntarctica en Flickr
eightydaysjet en Flickr
Farrukh en Flickr
Andy Wilson en Flickr
Valerie Reneé en Flickr
Paul Keller en Flickr
Marc Wesel en Flickr
Matteo Tarenghi en Flickr
JD Hancock en Flickr
Smabs Sputzer (1956-2017) en Flickr
Loco Races en Flickr
Cameron Daigle en Flickr

More Related Content

PDF
REST APIs with Spring
PDF
Introducing Playwright's New Test Runner
PDF
Understanding Reactive Programming
PDF
Spring Framework - Spring Security
PDF
[수정본] 우아한 객체지향
PDF
Rediscovering Spring with Spring Boot(1)
PDF
Microservices with Java, Spring Boot and Spring Cloud
PPTX
Spring boot - an introduction
REST APIs with Spring
Introducing Playwright's New Test Runner
Understanding Reactive Programming
Spring Framework - Spring Security
[수정본] 우아한 객체지향
Rediscovering Spring with Spring Boot(1)
Microservices with Java, Spring Boot and Spring Cloud
Spring boot - an introduction

What's hot (20)

PDF
[WSO2 API Manager Community Call] Mastering JWTs with WSO2 API Manager
PDF
Microservice With Spring Boot and Spring Cloud
PDF
Playwright: A New Test Automation Framework for the Modern Web
PPTX
Technical Tips: Visual Regression Testing and Environment Comparison with Bac...
PDF
Deep Dive Java 17 Devoxx UK
PPTX
An introduction to Maven
PDF
Java Strings Tutorial | String Manipulation in Java | Java Tutorial For Begin...
PDF
Clean architectures with fast api pycones
PPTX
Java Spring Framework
PPT
Spring data presentation
PPTX
CICD Pipeline Using Github Actions
PDF
[162] jpa와 모던 자바 데이터 저장 기술
PDF
Cypress-vs-Playwright: Let the Code Speak
PDF
Kotlin for Android Development
PPTX
API Security : Patterns and Practices
PDF
GitHub Actions in action
PPT
Java And Multithreading
PDF
Spring Boot
PDF
#살아있다 #자프링외길12년차 #코프링2개월생존기
PPT
Java collections concept
[WSO2 API Manager Community Call] Mastering JWTs with WSO2 API Manager
Microservice With Spring Boot and Spring Cloud
Playwright: A New Test Automation Framework for the Modern Web
Technical Tips: Visual Regression Testing and Environment Comparison with Bac...
Deep Dive Java 17 Devoxx UK
An introduction to Maven
Java Strings Tutorial | String Manipulation in Java | Java Tutorial For Begin...
Clean architectures with fast api pycones
Java Spring Framework
Spring data presentation
CICD Pipeline Using Github Actions
[162] jpa와 모던 자바 데이터 저장 기술
Cypress-vs-Playwright: Let the Code Speak
Kotlin for Android Development
API Security : Patterns and Practices
GitHub Actions in action
Java And Multithreading
Spring Boot
#살아있다 #자프링외길12년차 #코프링2개월생존기
Java collections concept
Ad

Similar to Dataclasses en Python 3.7: Empieza a borrar código (11)

PPTX
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
PPTX
DDDesign Challenges
PDF
Haskell Tour (Part 3)
PDF
Advanced python
PPTX
Functional DDD
PDF
Eric Lafortune - ProGuard and DexGuard for optimization and protection
PPT
Jeop game-final-review
PDF
A Few of My Favorite (Python) Things
PDF
Taking Perl to Eleven with Higher-Order Functions
PDF
Functional Programming with Groovy
PDF
Madrid gug - sacando partido a las transformaciones ast de groovy
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
DDDesign Challenges
Haskell Tour (Part 3)
Advanced python
Functional DDD
Eric Lafortune - ProGuard and DexGuard for optimization and protection
Jeop game-final-review
A Few of My Favorite (Python) Things
Taking Perl to Eleven with Higher-Order Functions
Functional Programming with Groovy
Madrid gug - sacando partido a las transformaciones ast de groovy
Ad

Recently uploaded (20)

DOCX
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
PDF
Time Tracking Features That Teams and Organizations Actually Need
PDF
AI-Powered Threat Modeling: The Future of Cybersecurity by Arun Kumar Elengov...
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Salesforce Agentforce AI Implementation.pdf
PPTX
Oracle Fusion HCM Cloud Demo for Beginners
PDF
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
PDF
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
PPTX
Computer Software and OS of computer science of grade 11.pptx
PPTX
Introduction to Windows Operating System
PDF
Wondershare Recoverit Full Crack New Version (Latest 2025)
PPTX
Cybersecurity: Protecting the Digital World
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
PPTX
Custom Software Development Services.pptx.pptx
PDF
Ableton Live Suite for MacOS Crack Full Download (Latest 2025)
PPTX
Patient Appointment Booking in Odoo with online payment
PPTX
"Secure File Sharing Solutions on AWS".pptx
PPTX
chapter 5 systemdesign2008.pptx for cimputer science students
PDF
Types of Token_ From Utility to Security.pdf
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
Time Tracking Features That Teams and Organizations Actually Need
AI-Powered Threat Modeling: The Future of Cybersecurity by Arun Kumar Elengov...
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Salesforce Agentforce AI Implementation.pdf
Oracle Fusion HCM Cloud Demo for Beginners
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
Computer Software and OS of computer science of grade 11.pptx
Introduction to Windows Operating System
Wondershare Recoverit Full Crack New Version (Latest 2025)
Cybersecurity: Protecting the Digital World
wealthsignaloriginal-com-DS-text-... (1).pdf
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
Custom Software Development Services.pptx.pptx
Ableton Live Suite for MacOS Crack Full Download (Latest 2025)
Patient Appointment Booking in Odoo with online payment
"Secure File Sharing Solutions on AWS".pptx
chapter 5 systemdesign2008.pptx for cimputer science students
Types of Token_ From Utility to Security.pdf

Dataclasses en Python 3.7: Empieza a borrar código

  • 1. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 2. Tech Lead en Qnective AG Encantador de serpientes desde v2.2 Trabajo en remoto desde 2016 Incapaz de soportarun invierno de verdad desde2016 Apenas sé hablar español técnico Gran amante de las listas Como esta Python Venga! Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 3. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 from dataclasses import dataclass @dataclass class Point: x: int y: int p1 = Point(0, 0) print(f'{p1}: x={p1.x}, y={p1.y}') p2 = Point(x=0, y=0) print(f'{p1} == {p2} -> {p1 == p2}’) Point(x=0, y=0): x=0, y=0 Point(x=0, y=0) == Point(x=0, y=0) -> True
  • 4. El dato estructurado De tuplas a clases Añadiendo funcionalidad a una clase Dataclass Casosmás simples Comparabilidad Hashabilidad Campos Valores por defecto Herencia __slots__ Funciones de apoyo Proyectos de terceros Alternativas Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 5. El dato estructurado Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 6. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 red = 255, 0, 0 orange = (255, 165, 0) green = tuple(0, 255, 0) >>> orange[0] 255 >>> r, g, b = orange >>> g 165
  • 7. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 red = list((255, 0, 0)) orange = [255, 165, 0]
  • 8. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 red = dict(red=255, green=0, blue=0) orange = {'red': 255, 'green': 165, 'blue': 0} >>> orange[‘blue’] 0
  • 9. ( ) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 from collections import namedtuple Colour = namedtuple( 'Colour', 'red green blue') red = Colour(255, 0, 0) orange = Colour(red=255, green=165, blue=0) >>> orange.red 255
  • 10. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 from typing import NamedTuple class Colour(NamedTuple): red: int green: int blue: int = 0 # default! red = Colour(255, 0) orange = Colour(red=255, green=165) >>> red.red 255 >>> orange.blue 0
  • 11. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 from types import SimpleNamespace red = SimpleNamespace(red=255, green=0, blue=0) >>> red.red 255
  • 12. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 class Colour: def __init__(self, red, green, blue=0): self.red = red self.green = green self.blue = blue red = Colour(255, 0) orange = Colour(red=255, green=165) >>> red.red 255 >>> orange.blue 0
  • 13. >>> print(red) <__main__.Colour object at 0x0000019119B09358> Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 14. def __repr__(self): return ( f"{self.__class__.__name__}(" f"red={self.red}, green={self.green}, " f"blue={self.blue})") >>> print(red) Colour(red=255, green=0, blue=0) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 15. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 class Colour: def __init__(self, red, green, blue=0): self.red = red self.green = green self.blue = blue def __repr__(self): return (f"{self.__class__.__name__}(" f"red={self.red}, green={self.green}, " f"blue={self.blue})")
  • 16. >>> red1 = Colour(255, 0, 0) >>> red2 = Colour(255, 0, 0) >>> red1 == red2 False >>> red1 == red1 True Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 17. def __eq__(self, other): if other.__class__ is not self.__class__: return NotImplemented return (self.red, self.green, self.blue) == ( other.red, other.green, other.blue) >>> red1 = Colour(255, 0, 0) >>> red2 = Colour(255, 0, 0) >>> red1 == red2 True >>> red1 is red2 False Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 18. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 class Colour: def __init__(self, red, green, blue=0): self.red = red self.green = green self.blue = blue def __repr__(self): return (f"{self.__class__.__name__}(" f"red={self.red}, green={self.green}, " f"blue={self.blue})") def __eq__(self, other): if other.__class__ is not self.__class__: return NotImplemented return (self.red, self.green, self.blue) == ( other.red, other.green, other.blue)
  • 19. >>> list(sorted([orange, red])) Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: '<' not supported between instances of 'Colour' and 'Colour' Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 20. def __lt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) < ( other.red, other.green, other.blue) return NotImplemented ... >>> list(sorted([orange, red])) [Colour(red=255, green=0, blue=0), Colour(red=255, green=165, blue=0)] Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 21. class Colour: def __init__(self, red, green, blue=0): self.red = red self.green = green self.blue = blue def __repr__(self): return (f"{self.__class__.__name__}(" f"red={self.red}, green={self.green}, " f"blue={self.blue})") def __eq__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) == ( other.red, other.green, other.blue) return NotImplemented def __ge__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) >= ( other.red, other.green, other.blue) return NotImplemented def __gt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) > ( other.red, other.green, other.blue) return NotImplemented def __le__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) <= ( other.red, other.green, other.blue) return NotImplemented def __lt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) < ( other.red, other.green, other.blue) return NotImplemented Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 22. def __delattr__(self, name): raise TypeError(f'cannot delete field {name}') def __setattr__(self, name, value): raise TypeError(f'cannot assign to field {name}’) >>> red = Colour(255, 0, 0) Traceback (most recent call last): File "<input>", line 1, in <module> File "<input>", line 4, in __init__ File "<input>", line 48, in __setattr__ TypeError: cannot assign to field red Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 23. def __init__(self, red, green, blue=0): object.__setattr__(self, "red", red) object.__setattr__(self, "green", green) object.__setattr__(self, "blue", blue) >>> red = Colour(255, 0, 0) >>> red.blue = 1 Traceback (most recent call last): File "<input>", line 1, in <module> File "<input>", line 23, in __setattr__ TypeError: cannot assign to field blue Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 24. def __hash__(self): return hash((self.red, self.green, self.blue)) >>> hash(red) 1738572376461218158 >> set([red]) {Colour(red=255, green=0, blue=0)} Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 25. class Colour: def __init__(self, red, green, blue=0): object.__setattr__(self, "red", red) object.__setattr__(self, "green", green) object.__setattr__(self, "blue", blue) def __repr__(self): return (f"{self.__class__.__name__}(" f"red={self.red}, green={self.green}, " f"blue={self.blue})") def __eq__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) == ( other.red, other.green, other.blue) return NotImplemented def __ge__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) >= ( other.red, other.green, other.blue) return NotImplemented def __gt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) > ( other.red, other.green, other.blue) return NotImplemented def __le__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) <= ( other.red, other.green, other.blue) return NotImplemented def __lt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) < ( other.red, other.green, other.blue) return NotImplemented def __delattr__(self, name): raise TypeError(f'cannot delete field {name}') def __setattr__(self, name, value): raise TypeError(f'cannot assign to field {name}') def __hash__(self): return hash((self.red, self.green, self.blue)) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 26. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 Añade. Otro. Campo.
  • 27. El módulo dataclasses Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 28. from dataclasses import dataclass @dataclass class Colour: red: int green: int blue: int orange = Colour(red=255, green=165, blue=0) red = Colour(255, 0, 0) >>> red Colour(red=255, green=0, blue=0) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 29. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 # Python 3.5 from typing import Optional def fun(width: float, name: Optional[str]=None) -> None: pass # Python 3.6 temperature: float temperature = 'cold' class Measurement: speed: float __annotations__
  • 30. from dataclasses import dataclass @dataclass class Colour: red: int green: int blue: int orange = Colour(red=255, green=165, blue=0) red = Colour(255, 0, 0) red2 = Colour(255, 0, 0) >>> red == red2 True Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 31. from dataclasses import dataclass @dataclass class Colour: red: int green: int blue: int red = Colour(255, 0, 0) >>> red.red = 240 >>> red Colour(red=240, green=0, blue=0) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 32. from dataclasses import dataclass @dataclass class Colour: red: int green: int blue: int >>> list(sorted([orange, red])) Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: '<' not supported between instances of 'Colour' and 'Colour' Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 33. @dataclass(order=True) class Colour: red: int green: int blue: int >>> list(sorted([orange, red])) [Colour(red=255, green=0, blue=0), Colour(red=255, green=165, blue=0)] Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 34. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 def dataclass(_cls=None, *, order=False): def wrap(cls): return _process_class(cls, order) # See if we're being called as @dataclass # or @dataclass(). if _cls is None: # We're called with parens. return wrap # We're called as @dataclass without parens. return wrap(_cls)
  • 35. @dataclass(order=True) class Colour: red: int green: int blue: int >>> hash(red) Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: unhashable type: 'Colour' Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 36. @dataclass(order=True, frozen=True) class Colour: red: int green: int blue: int >>> hash(red) 1738572376461218158 >> set([red]) {Colour(red=255, green=0, blue=0)} Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 37. @dataclass(order=True, frozen=True) class Colour: red: int green: int blue: int >>> red.red = 240 Traceback (most recent call last): File "<input>", line 1, in <module> File "<string>", line 3, in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'red' Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 38. Dataclass @dataclass(order=True, frozen=True) class Colour: red: int green: int blue: int Claseartesanal • class Colour: def __init__(self, red, green, blue=0): object.__setattr__(self, "red", red) object.__setattr__(self, "green", green) object.__setattr__(self, "blue", blue) def __repr__(self): return (f"{self.__class__.__name__}(" f"red={self.red}, green={self.green}, " f"blue={self.blue})") def __eq__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) == ( other.red, other.green, other.blue) return NotImplemented def __ge__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) >= ( other.red, other.green, other.blue) return NotImplemented def __gt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) > ( other.red, other.green, other.blue) return NotImplemented def __le__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) <= ( other.red, other.green, other.blue) return NotImplemented def __lt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) < ( other.red, other.green, other.blue) return NotImplemented def __delattr__(self, name): raise TypeError(f'cannot delete field {name}') def __setattr__(self, name, value): raise TypeError(f'cannot assign to field {name}') def __hash__(self): return hash((self.red, self.green, self.blue)) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 40. Los campos de una dataclass Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 41. @dataclass class Colour: red: int green: int blue: int = 0 orange = Colour(red=255, green=165) red = Colour(255, 0) >>> red Colour(red=255, green=0, blue=0) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 42. from typing import List @dataclass class Employee: name: str surname: str children: List[str] = [] john = Employee('John', 'Green') hank = Employee('Hank', 'Green’) john.children.append('Henry') Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 43. Traceback (most recent call last): File "<input>", line 3, in <module> File "dataclasses.py", line 966, in dataclass return wrap(_cls) File "dataclasses.py", line 958, in wrap return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen) File "dataclasses.py", line 809, in _process_class for name, type in cls_annotations.items()] File "dataclasses.py", line 809, in <listcomp> for name, type in cls_annotations.items()] File "dataclasses.py", line 702, in _get_field raise ValueError(f'mutable default {type(f.default)} for field ' ValueError: mutable default <class 'list'> for field children is not allowed: use default_factory Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 44. from dataclasses import dataclass, field from typing import List @dataclass class Employee: name: str surname: str children: List[str] = field(default_factory=list) john = Employee('John', 'Green') hank = Employee('Hank', 'Green') john.children.append('Henry') john.children.append('Alice’) >>> hank.children [] Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 45. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 __annotations__ dataclasses.Field __dataclass_fields__
  • 47. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 from typing import ClassVar @dataclass class Colour: MAX: ClassVar[int] = 255 red: int green: int blue: int = 0 red = Colour(255, 0) orange = Colour(255, 165) >>> red.MAX 255
  • 48. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 from dataclasses import dataclass, field, InitVar @dataclass class Address: protocol: InitVar[str] host: InitVar[str] url: str = field(init=False) def __post_init__(self, protocol, host): self.url = f'{protocol}://{host}/' addr = Address('http', ‘example.com’) >>> addr Address(url='http://google.com/')
  • 49. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 @dataclass class Point1d: x: float @dataclass class Point2d(Point1d): y: float @dataclass class Point3d(Point2d): z: float p1 = Point1d(11.1) p2 = Point2d(22.2, 33.3) p3 = Point3d(44.4, 55.5, 66.6) >>> p1, p2, p3 (Point1d(x=11.1), Point2d(x=22.2, y=33.3), Point3d(x=44.4, y=55.5, z=66.6))
  • 50. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 @dataclass class Colour: __slots__ = ( 'red’, 'green’, 'blue') red: int green: int blue: int >>> red.check = True Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'Colour' object has no attribute 'check' Rapidez de acceso Restricción de creación de campos Ahorro de espacio ¡Sin valores por defecto!
  • 51. Funciones de apoyo Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 52. fields Lista los campos guardados. Funciona con instancias y clases. asdict Convierte un objeto en diccionario de forma recursiva astuple Convierte un objeto en tupla de forma recursiva replace Crea una copia (no profunda) de un objeto con algunos campos cambiados de valor. is_dataclass Comprueba si un objeto o clase es una dataclass make_dataclass Crea una nueva clase con dataclass Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 53. fields Lista los campos guardados. Funciona con instancias y clases. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 >>> dataclasses.fields(red) (Field(name='red’,... Field(name='green',type=<class 'int'>,default=<dataclasses._MISSING_TYPE object at 0x0000028B13380208>,default_factory=<dataclasses._MISSI NG_TYPE object at 0x0000028B13380208>,init=True,repr=True,hash=None,compa re=True,metadata=mappingproxy({}),_field_type=_FIELD), Field(name='blue’,...))
  • 54. asdict Convierte un objeto en diccionario de forma recursiva Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 >>> dataclasses.asdict(red) {'red': 255, 'green': 0, 'blue': 0}
  • 55. astuple Convierte un objeto en tupla de forma recursiva Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 >>> dataclasses.astuple(red) (255, 0, 0)
  • 56. replace Crea una copia (no profunda) de un objeto con algunos campos cambiados de valor. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 >>> red2 = dataclasses.replace(red, blue=12) >>> red2 Colour(red=255, green=0, blue=12)
  • 57. is_dataclass Comprueba si un objeto o clase es una dataclass Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 >>> dataclasses.is_dataclass(red) True >>> dataclasses.is_dataclass(Colour) True >>> dataclasses.is_dataclass([]) False
  • 58. make_dataclass Crea una nueva clase con dataclass Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 from dataclasses import make_dataclass Colour = make_dataclass('Colour', fields=[('red', int), ('green', int), ('blue', int)]) red = Colour(255, 0, 0) orange = Colour(255, 165, 0)
  • 59. Proyectos relacionados Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 60. dataslots Decorador with_slots, añade slots a una dataclass. dataclass-factory Crea instancias de dataclasses a partir de diccionarios. Inverso a asdict. strictclasses Decorador que hace que se comprueben tipos en asignación. dataclassinspector Intenta mostrar el equivalente al código generado por una dataclass. Intenta. fistro Genera instancias de dataclasses con datos para pruebas. Fixtures. dataclasses-jsonschema Crea JSON schema a partir de una dataclass. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 61. La alternativa Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 62. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 import attr @attr.s class Colour: red: int = attr.ib() green: int = attr.ib() blue: int = attr.ib() red = Colour(255, 0, 0) >>> red Colour(red=255, green=0, blue=0)
  • 63. Funciona desde Python 2.7 Soporta __slots__ Validadores Convertidores Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 64. La recta final Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 65. El dato estructurado De tuplas a clases Añadiendo funcionalidad a una clase Dataclass Casosmás simples Comparabilidad Hashabilidad Campos Valores por defecto Herencia __slots__ Funciones de apoyo Proyectos de terceros Alternativas Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 66. Dataclass @dataclass(order=True, frozen=True) class Colour: red: int green: int blue: int Claseartesanal • class Colour: def __init__(self, red, green, blue=0): object.__setattr__(self, "red", red) object.__setattr__(self, "green", green) object.__setattr__(self, "blue", blue) def __repr__(self): return (f"{self.__class__.__name__}(" f"red={self.red}, green={self.green}, " f"blue={self.blue})") def __eq__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) == ( other.red, other.green, other.blue) return NotImplemented def __ge__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) >= ( other.red, other.green, other.blue) return NotImplemented def __gt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) > ( other.red, other.green, other.blue) return NotImplemented def __le__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) <= ( other.red, other.green, other.blue) return NotImplemented def __lt__(self, other): if other.__class__ is self.__class__: return (self.red, self.green, self.blue) < ( other.red, other.green, other.blue) return NotImplemented def __delattr__(self, name): raise TypeError(f'cannot delete field {name}') def __setattr__(self, name, value): raise TypeError(f'cannot assign to field {name}') def __hash__(self): return hash((self.red, self.green, self.blue)) Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 67. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 Añade. Otro. Campo.
  • 68. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018
  • 69. Jacobo de Vera | @jovianjake | PyDay Tenerife 2018 Todd Ehlers en Flickr Philippe_ en Flickr Leo Hidalgo en Flickr Antonio Trogu en Flickr Bruce Baugh en Flickr VivaAntarctica en Flickr eightydaysjet en Flickr Farrukh en Flickr Andy Wilson en Flickr Valerie Reneé en Flickr Paul Keller en Flickr Marc Wesel en Flickr Matteo Tarenghi en Flickr JD Hancock en Flickr Smabs Sputzer (1956-2017) en Flickr Loco Races en Flickr Cameron Daigle en Flickr