-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create first version of dataclass examples
- Loading branch information
Robert Richter
committed
Nov 24, 2019
1 parent
74148da
commit 2a6b48f
Showing
9 changed files
with
263 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
""" | ||
Ukázka vytvoření objektu z běžné třídy | ||
Pro inicializaci se využívá dunder (double underscore) metoda __init__() | ||
Dunder metody nemá smysl ve většině případů volat přímo, ale jsou volány Python interpretem | ||
při nějaké události. V případě metody __init__() je události vytvoření instance třídy Person | ||
""" | ||
|
||
# Třída Person | ||
class Person: | ||
def __init__(self, name, surname, age, height): | ||
self.name = name | ||
self.surname = surname | ||
self.age = age | ||
self.height = height | ||
|
||
|
||
# Vytvoření instance třídy Person | ||
person = Person("John", "Doe", 66, 180) | ||
print(person) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
""" | ||
Ukázka implementace reprezentace vyplnění dunder metody __repr__() | ||
Ve chvíli, kdy se instance třídy Person dá "vypsat" funkcí print, zavolá se dunder metoda | ||
__repr__(), která printu předá to, co jsme si nadefinovali. | ||
""" | ||
|
||
|
||
class Person: | ||
def __init__(self, name, surname, age, height): | ||
self.name = name | ||
self.surname = surname | ||
self.age = age | ||
self.height = height | ||
|
||
def __repr__(self): | ||
return f"class: {self.__class__.__name__}," \ | ||
f" name: {self.name}, surname: {self.surname}, age: {self.age}, height: {self.height}" | ||
|
||
|
||
person = Person("John", "Doe", 66, 180) | ||
print(person) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
""" | ||
Ukázka implementace reprezentace vyplnění dunder metody __repr__() | ||
Funguje to obdobně jako u __repr__() | ||
Dunder metody jsou volány při porovnávání instancí příslušnými operátory | ||
__eq__() == | ||
__ne__() != | ||
__gt__() > | ||
__lt__() < | ||
__ge__() >= | ||
__le__() <= | ||
V příkladu jsou některé zakomentované. Je to z důvodu, že ve skutečnosti všechny nejsou třeba. | ||
Python si dokáže odvodit opačnou funkci. Např. z __eq__ si odvodí __ne__ | ||
""" | ||
|
||
class Person: | ||
def __init__(self, name, surname, age, height): | ||
self.name = name | ||
self.surname = surname | ||
self.age = age | ||
self.height = height | ||
|
||
def __repr__(self): | ||
return f"class: {self.__class__.__name__}," \ | ||
f" name: {self.name}, surname: {self.surname}, age: {self.age}, height: {self.height}" | ||
|
||
def __eq__(self, other): | ||
return (self.name, self.surname, self.age, self.height) == \ | ||
(other.name, other.surname, other.age, other.height) | ||
|
||
def __lt__(self, other): | ||
return ((self.name, self.surname, self.age, self.height) < | ||
(other.name, other.surname, other.age, other.height)) | ||
|
||
def __ge__(self, other): | ||
return ((self.name, self.surname, self.age, self.height) >= | ||
(other.name, other.surname, other.age, other.height)) | ||
|
||
# def __ne__(self, other): | ||
# return (self.name, self.surname, self.age, self.height) != \ | ||
# (other.name, other.surname, other.age, other.height) | ||
|
||
# def __le__(self, other): | ||
# return ((self.name, self.surname, self.age, self.height) <= | ||
# (other.name, other.surname, other.age, other.height)) | ||
|
||
# def __gt__(self, other): | ||
# return ((self.name, self.surname, self.age, self.height) > | ||
# (other.name, other.surname, other.age, other.height)) | ||
|
||
|
||
john = Person("John", "Doe", 66, 180) | ||
john_copy = Person("John", "Doe", 66, 180) | ||
great_zohn = Person("Zohn", "Zow", 666, 1800) | ||
|
||
print(f"{john}\n{john_copy}\njohn == john_copy: {john == john_copy}\n") | ||
print(f"{john}\n{great_zohn}\njohn == great_zohn: {john == great_zohn}\n") | ||
print(f"{john}\n{great_zohn}\njohn < great_zohn: {john < great_zohn}\n") | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
""" | ||
Doteď by nám příklady fungovaly i na starším Pythonu. Nyní je již třeba minimálně verze 3.7. | ||
Příklad ukazuje sílu datových tříd, kdy nemusíme implementovat žádné dunder metody pro inicializaci, | ||
reprezentaci ani porovnání, vše je za nás vytvořeno. | ||
""" | ||
|
||
from dataclasses import dataclass | ||
|
||
""" | ||
Datová třída se vytváří použitím dekorátoru @dataclass (v tomto konkrétním příkladu s parametrem | ||
order=True). Dekorátor jsme si naimportovali z modulu dataclassses, který je součástí interpretu, | ||
viz. výše. | ||
name:str Toto je tzv. typová anotace, která Pythonu řekne, o jaký datový typ se jedná (v tomto | ||
konkrétním případě o řetězec). Tuto informaci potřebuje pro potřeby porovnávání. | ||
""" | ||
@dataclass(order=True) | ||
class Person: | ||
name: str | ||
surname: str | ||
age: int | ||
height: int | ||
|
||
|
||
john = Person("John", "Doe", 66, 180) | ||
john_copy = Person("John", "Doe", 66, 180) | ||
great_zohn = Person("Zohn", "Zow", 666, 1800) | ||
|
||
print(f"{john}\n{john_copy}\njohn == john_copy: {john == john_copy}\n") | ||
print(f"{john}\n{great_zohn}\njohn == great_zohn: {john == great_zohn}\n") | ||
print(f"{john}\n{great_zohn}\njohn < gret_zohn: {john < great_zohn}\n") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
""" | ||
Ukázka vytvoření vlastního deokorátoru | ||
""" | ||
|
||
def world(function): | ||
def wrapper(): | ||
return function() + "world!" | ||
return wrapper | ||
|
||
|
||
def hi(): | ||
return "Hi " | ||
|
||
# Takhle by vypadalo použití dekorátoru v případě, že by neexistovala syntaxe s @ - viz. níže | ||
decorated_hi = world(hi) | ||
print(decorated_hi()) | ||
|
||
# Standardní použití námi vytvořeného dekorátoru | ||
@world | ||
def hello(): | ||
return "Hello " | ||
|
||
|
||
print(hello()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
""" | ||
Tento příklad ukazuje, jak datové třídy podrobněji nastavovat. V předchozích příkladech | ||
nám do porovnávání či reprezentace vstupovali veškeré atributy třídy. Tady si ukážeme, jak můžeme | ||
některé vynechat, nebo jak nastavit implicitní hodnoty. | ||
""" | ||
|
||
from dataclasses import dataclass, field | ||
|
||
|
||
@dataclass(order=True) | ||
class Person: | ||
name: str = field(compare=False, default="John") | ||
surname: str = field(compare=False, default="Dow") | ||
age: int = field(repr=False, default=66) | ||
height: int = field(compare=False, repr=False, default=180) | ||
|
||
|
||
john = Person() | ||
john_bad_copy = Person(surname="Doh") | ||
great_zohn = Person("Zohn", "Zow", 10, 1800) | ||
|
||
print(f"{john}\n{john_bad_copy}\njohn == john_bad_copy: {john == john_bad_copy}\n") | ||
print(f"{john}\n{great_zohn}\njohn == great_zohn: {john == great_zohn}\n") | ||
print(f"{john}\n{great_zohn}\njohn < great_zohn: {john < great_zohn}\n") | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
""" | ||
Ukázka parametru frozen - zajistí nám, že vytvořené instance již nepůjdou dále měnit. | ||
""" | ||
|
||
from dataclasses import dataclass | ||
|
||
|
||
|
||
@dataclass | ||
class HotJohn: | ||
name: str = "John" | ||
surname: str = "Doe" | ||
age: int = 66 | ||
height: int = 180 | ||
|
||
|
||
@dataclass(frozen=True) | ||
class FrozenJohn: | ||
name: str = "John" | ||
surname: str = "Doe" | ||
age: int = 66 | ||
height: int = 180 | ||
|
||
|
||
hot_john = HotJohn() | ||
frozen_john = FrozenJohn() | ||
|
||
print(hot_john) | ||
hot_john.height = 170 | ||
hot_john.surname = "Doh" | ||
hot_john.weight = 80 | ||
print(hot_john) | ||
print(hot_john.weight) | ||
|
||
frozen_john.height = 80 | ||
frozen_john.weight = 80 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
""" | ||
Ukázka všech parametrů, které můžeme při vytvoření datové třídy využít. | ||
order - defaultně False, při zapnutí se implementuje metody __lt__, __gt__, __eg__, __el__ | ||
eq - defaultně True, při zapnutí implementuje metody __eq__, __ne__ | ||
init - defaultně True, implementuje __init__ metodu | ||
repr - defaultně True, implementuje __repr__ metodu | ||
frozen - defaultně False, při zapnutí nám nedovolí vytvořenou instanci měnit | ||
unsafe_hash - Nebudeme vysvětlovat, protože se jedná o složitější koncept a není | ||
pravděpodobné, že bychom jej opravdu potřebovali. Zjednodušeně řečeno, ovlivňuje zda bude | ||
implementována dunder metoda __hash__. | ||
Pozor, neovlivňuje to sám, ale vždy jde o kombinaci parametrů order, frozen, unsafe_hash. | ||
""" | ||
|
||
from dataclasses import dataclass, field | ||
|
||
|
||
@dataclass(order=True, frozen=False, unsafe_hash=False, init=True, eq=True, repr=True) | ||
class Person: | ||
name: str = field(compare=False, default="John") | ||
surname: str = field(compare=False, default="Doe") | ||
age: int = field(repr=False, default=66) | ||
height: int = field(compare=False, repr=False, default=180) | ||
|
||
|
||
john = Person() | ||
john_bad_copy = Person(surname="Doh") | ||
great_zohn = Person("Zohn", "Zow", 10, 1800) | ||
|
||
print(f"{john}\n{john_bad_copy}\njohn == john_bad_copy: {john == john_bad_copy}\n") | ||
print(f"{john}\n{great_zohn}\njohn == great_zohn: {john == great_zohn}\n") | ||
print(f"{john}\n{great_zohn}\njohn < great_zohn: {john < great_zohn}\n") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,7 @@ | ||
# pyvo-hk-dataclasses | ||
Ukázka použití datových tříd v Pythonu 3.7 | ||
# Datové třídy z Pythonu 3.7 | ||
|
||
Projekt obsahuje jednoduché příklady demonstrující výhody využití datových tříd. | ||
Příklady na sebe logicky navazují, v každém dalším je představena nová funkcionalita. | ||
Proto je dobré začít od 01_init.py | ||
|
||
Pro funkčnost ukázek je potřeba Python verze 3.7 nebo vyšší. |