This will be a look/tutorial at the biggest news with Python 3.7 which was @dataclass.
Can just write a class and test it out.
An other thing to look at is that
These are hints and will not affect when say use a wrong type at run time.
To actually catch type errors, type checkers like Mypy can be run on your source code.
I used Raymond Hettinger Pycon 2018 Talk about @dataclasse as help to write this.
Here we see the missing method like eg
Adding to decorator and field
Now is @dataclass orderable(not bye default) immutability and hashability is added.
Also tell that
So now it will only sort bye price of vehicle.
Adding methods
This works as normal method in a class,here can use Type hint or not.
Mixed Stuff
It run after the auto-generated
@dataclass support inheritance like normal python classes.
Thoughts?
I can like the look and use of it,as get a lot of stuff generated for free
This is a open tutorials,so if someone has tested or have a opinions about @dataclass feel free to posts about it here.
Can just write a class and test it out.
from dataclasses import dataclass, field from decimal import Decimal @dataclass() class Vehicle: vehicle_type: str name : str price: DecimalSo this @dataclass generate
.__init__(), .__repr__(), and .__eq__()
for you.An other thing to look at is that
type hint
(class annotations) is mandatory when defining the fields in your data. These are hints and will not affect when say use a wrong type at run time.
To actually catch type errors, type checkers like Mypy can be run on your source code.
Use class:
# Instantiate class >>> vehicle_1 = Vehicle('Car', 'Bmw', Decimal('200_000.55')) >>> vehicle_2 = Vehicle('Bus', 'Volvo', Decimal('1000_000.99')) # Call instance objects >>> vehicle_1.name 'Bmw' >>> vehicle_1.price Decimal('200000.55') >>> vehicle_2.vehicle_type 'Bus' >>> # __repr__ in action >>> vehicle_1 Vehicle(vehicle_type='Car', name='Bmw', price=Decimal('200000.55')) >>> print(vehicle_2) Vehicle(vehicle_type='Bus', name='Volvo', price=Decimal('1000000.99')) >>> # __eq__ in action >>> vehicle_1 == Vehicle('Car', 'Bmw', Decimal('200_000.55')) True >>> vehicle_1 == Vehicle('Bus', 'Volvo', Decimal('1000_000.99')) False # Some use of class with f-string >>> print(f'The bus cost {vehicle_2.price - vehicle_1.price}$ more than the car') The bus cost 800000.44$ more than the car >>> # They are type hint,nothing happen if assassin a int to vehicle_type: str >>> vehicle_1 = Vehicle('Car', 'Bmw', 200_000.55) >>> vehicle_1.name = 9999999 >>> vehicle_1.name 9999999So what is going on in background,here my take on it writing the generated code for this @dataclass.
I used Raymond Hettinger Pycon 2018 Talk about @dataclasse as help to write this.
Generated code:
Here we see the missing method like eg
__init__
.Adding to decorator and field
from dataclasses import dataclass, field from decimal import Decimal @dataclass(order=True, frozen=True) class Vehicle: kind: str = field(compare=False) name : str = field(compare=False) price: DecimalJust doing this will generate about 40 more lines of code.
Quote:order:
If true (the default is False), __lt__(), __le__(), __gt__(), and __ge__() methods will be generated.
frozen:
If true (the default is False), assigning to fields will generate an exception.
This emulates read-only frozen instances. If __setattr__() or __delattr__() is defined in the class,
then TypeError is raised. See the discussion below.
Now is @dataclass orderable(not bye default) immutability and hashability is added.
Also tell that
str
shall not be in comparison when eg using sorted()
.So now it will only sort bye price of vehicle.
Use class:
# Instantiate class >>> vehicle_1 = Vehicle('Car', 'Bmw', 200_000.55) >>> vehicle_2 = Vehicle('Bus', 'Volvo', 1000_000.99) >>> vehicle_3 = Vehicle('Cycle', 'Colnago', 10000) # Sort bye price >>> sorted((vehicle_1, vehicle_2, vehicle_3)) [Vehicle(kind='Cycle', name='Colnago', price=10000), Vehicle(kind='Car', name='Bmw', price=200000.55), Vehicle(kind='Bus', name='Volvo', price=1000000.99)] # High to low >>> sorted((vehicle_1, vehicle_2, vehicle_3), reverse=True) [Vehicle(kind='Bus', name='Volvo', price=1000000.99), Vehicle(kind='Car', name='Bmw', price=200000.55), Vehicle(kind='Cycle', name='Colnago', price=10000)] # Instantiate class Duplicate >>> vehicle_1 = Vehicle('Car', 'Bmw', 200_000.55) >>> vehicle_2 = Vehicle('Bus', 'Volvo', 1000_000.99) >>> vehicle_2 = Vehicle('Bus', 'Volvo', 1000_000.99) >>> vehicle_3 = Vehicle('Cycle', 'Colnago', 10000) # Using set() to remove >>> set((vehicle_1, vehicle_2, vehicle_3)) {Vehicle(kind='Cycle', name='Colnago', price=10000), Vehicle(kind='Car', name='Bmw', price=200000.55), Vehicle(kind='Bus', name='Volvo', price=1000000.99)} # Is immutable >>> vehicle_1.name = 'Taxi' Traceback (most recent call last): File "<string>", line 428, in runcode File "<interactive input>", line 1, in <module> File "<string>", line 3, in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'name'
Adding methods
This works as normal method in a class,here can use Type hint or not.
from dataclasses import dataclass, field from decimal import Decimal @dataclass(order=True) class Vehicle: vehicle_type: str = field(compare=False) name : str = field(compare=False) price: Decimal def __str__(self): return f'{self.vehicle_type} {self.name} at cost of {self.price}$' @property def color_choice(self): if self.name == 'Bmw': print(f'Color choice is Black | Blue | Red for {self.name} {self.vehicle_type}') if self.name == 'Volvo': print(f'Color choice is Orange | Yellow | Green for {self.name} {self.vehicle_type}') if self.name == 'Colnago': print(f'Color choice is Dark Blue | Red/yellows(Mixed in Green)', f'| Stealth for {self.name} {self.vehicle_type}')
Use class:
# Instantiate class >>> vehicle_1 = Vehicle('Car', 'Bmw', Decimal('200_000.55')) >>> vehicle_2 = Vehicle('Bus', 'Volvo', Decimal('1000_000.99')) >>> vehicle_3 = Vehicle('Cycle', 'Colnago', Decimal('10_000')) >>> >>> # New added __str__ >>> print(vehicle_1) Car Bmw at cost of 200000.55$ >>> # Generated __repr___ >>> vehicle_1 Vehicle(vehicle_type='Car', name='Bmw', price=Decimal('200000.55')) >>> >>> # The new method >>> vehicle_2.color_choice Color choice is Orange | Yellow | Green for Volvo Bus >>> vehicle_3.color_choice Color choice is Dark Blue | Red/yellows(Mixed in Green) | Stealth for Colnago Cycle
Mixed Stuff
__post_init__
can be used to add stuff.It run after the auto-generated
__init__
.from dataclasses import dataclass, field @dataclass class MakeUpper: field_a: str field_b: str = field(default='') def __post_init__(self): self.orginal = self.field_b self.field_b = self.field_b.upper()
Use class:
>>> result = MakeUpper(field_a='a', field_b='all lowercase given') >>> result.field_a 'a' >>> result.orginal 'all lowercase given' >>> result.field_b 'ALL LOWERCASE GIVEN' >>> result.__annotations__ {'field_a': <class 'str'>, 'field_b': <class 'str'>}Inheritance
@dataclass support inheritance like normal python classes.
from dataclasses import dataclass, field @dataclass class Plantes: name: str size: int = 0 def __str__(self): return f'{self.name} size is {self.size}-km and temprature is {self.celsius}°C' @dataclass class Temprature(Plantes): celsius: int = 0
Use class:
>>> obj = Temprature('Venus', 6052, 465) >>> >>> # __repr__ >>> obj Temprature(name='Venus', size=6052, celsius=465) >>> >>> # __str__ >>> print(obj) Venus size is 6052-km and temprature is 465°C >>> >>> obj.celsius 465
__post_init__
is can be called in inheritance using super()
as a normal __init__
def __post_init__(self): super().__post_init__() #Call post init of Parent class print("Something")
Thoughts?
I can like the look and use of it,as get a lot of stuff generated for free

This is a open tutorials,so if someone has tested or have a opinions about @dataclass feel free to posts about it here.