{"id":28411,"date":"2024-07-24T05:00:00","date_gmt":"2024-07-24T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=28411"},"modified":"2024-07-26T09:01:21","modified_gmt":"2024-07-26T07:01:21","slug":"type-hints-w-jezyku-python","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/type-hints-w-jezyku-python\/","title":{"rendered":"Type hints w j\u0119zyku Python"},"content":{"rendered":"\n<p>W pracy z kodem kluczowa jest jego dobra czytelno\u015b\u0107, a jawne deklarowanie typ\u00f3w zmiennych mo\u017ce znacznie w tym pom\u00f3c. To w\u0142a\u015bnie type hinting (wskaz\u00f3wki typu) pe\u0142ni t\u0119 rol\u0119 w j\u0119zyku Python. Ta funkcjonalno\u015b\u0107, b\u0119d\u0105ca cz\u0119\u015bci\u0105 standardowej biblioteki Pythona, jest \u0142atwa w u\u017cyciu dzi\u0119ki wsparciu ze strony jego sk\u0142adni. Dzi\u0119ki temu ka\u017cdy, niezale\u017cnie od \u015brodowiska deweloperskiego i poziomu znajomo\u015bci j\u0119zyka, mo\u017ce z niej skorzysta\u0107.<\/p>\n\n\n\n<p>Mam nadziej\u0119, \u017ce ten artyku\u0142 zach\u0119ci Was do u\u017cywania wskaz\u00f3wek typu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dlaczego warto dba\u0107 o czytelno\u015b\u0107 kodu w Pythonie<\/strong><\/h2>\n\n\n\n<p>Zazwyczaj Python kojarzy si\u0119 z tworzeniem skrypt\u00f3w, interpretowanym kodem (a dok\u0142adniej <a href=\"https:\/\/pl.wikipedia.org\/wiki\/Kod_bajtowy\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >kodem bajtowym<\/a> powsta\u0142ym z kompilacji) i r\u00f3wnie\u017c dynamicznym typowaniem, czyli przypisywanym typu zmiennej podczas wykonywania programu, a nie przed jego wykonaniem.<\/p>\n\n\n\n<p>Je\u015bli j\u0119zyk jest dynamicznie typowany, to w jakim celu definiowa\u0107 w kodzie typy? Nawet <a href=\"https:\/\/cpp0x.pl\/dokumentacja\/standard-C++11\/auto\/731\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >standard C++ w wersji 11<\/a> zmieni\u0142 znaczenie s\u0142owa kluczowego auto i od tej wersji mo\u017cna u\u017cywa\u0107 go jako zast\u0119pczy typ zmiennej. Jednak w C++ najcz\u0119\u015bciej to mniejszo\u015b\u0107 kodu oznaczona jest typem <em>auto<\/em>, a kompilacja mimo wszystko zweryfikuje zgodno\u015b\u0107 typ\u00f3w w kodzie.<\/p>\n\n\n\n<p>W przypadku programu czy skryptu gdzie typ \u017cadnej zmiennej nie jest jasno okre\u015blony i nie jest weryfikowany na etapie kompilacji, do\u015b\u0107 \u0142atwo mo\u017cna stworzy\u0107 problematyczny kod, gdzie dodatkowo bez pokrycia testami jednostkowymi, rozro\u015bni\u0119ty projekt mo\u017ce by\u0107 pe\u0142en b\u0142\u0119d\u00f3w i trudny w utrzymaniu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Czym jest type hinting<\/strong><\/h2>\n\n\n\n<p>Python jest dynamicznie typowanym j\u0119zykiem. Mimo wszystko istnieje mo\u017cliwo\u015b\u0107 deklarowania typu poprzez type hinting, a funkcjonalno\u015b\u0107 ta zosta\u0142a wprowadzona oficjalnie <a href=\"https:\/\/docs.python.org\/3\/whatsnew\/3.5.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >w wersji Pythona 3.5<\/a>.<\/p>\n\n\n\n<p>To rozwi\u0105zanie pozwala na wskazywanie typ\u00f3w element\u00f3w takich jak:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>zmienne,<\/li>\n\n\n\n<li>pola klas,<\/li>\n\n\n\n<li>argumenty i typy zwracane dla funkcji oraz metod.<\/li>\n<\/ul>\n\n\n\n<p>Warto pami\u0119ta\u0107, \u017ce wskaz\u00f3wki typu to jednak tylko wskaz\u00f3wki i nie wp\u0142ywaj\u0105 one na wykonywanie programu. Mimo wszystko takie rozwi\u0105zanie polepsza czytelno\u015b\u0107 kodu, a samo IDE (Integrated Development Environments) cz\u0119sto wspiera type hints i umo\u017cliwia na przyk\u0142ad autouzupe\u0142nianie kodu. W po\u0142\u0105czeniu ze statyczn\u0105 analiz\u0105 kodu, o kt\u00f3rej dowiecie si\u0119 w innym artykule na blogu Sii: <a href=\"https:\/\/sii.pl\/blog\/statyczna-analiza-kodu-w-pythonie\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">Statyczna analiza kodu w Pythonie<\/a>, mo\u017cna r\u00f3wnie\u017c sprawdzi\u0107 kod pod k\u0105tem b\u0142\u0119d\u00f3w, w tym zwi\u0105zanych z typami zmiennych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wspierane typy<\/strong><\/h2>\n\n\n\n<p>Deklarowa\u0107 mo\u017cna typy wbudowane: <em>str<\/em>, <em>bool<\/em>, <em>float<\/em>, <em>int<\/em>. Wspierane s\u0105 r\u00f3wnie\u017c r\u00f3\u017cnego typu kontenery: <em>List<\/em>, <em>Dict<\/em>, <em>Set<\/em>, <em>Tuple<\/em>. Python nie ogranicza nas w \u0142\u0105czeniu wskaz\u00f3wek, mo\u017cna zdefiniowa\u0107 np.: <em>List[str]<\/em>, czy te\u017c <em>Dict[str, List[str]]<\/em>. Czasem wspierane s\u0105 zmienne kilku typ\u00f3w, u\u017cyteczne wtedy oka\u017ce si\u0119 <em>Union<\/em>, z pomoc\u0105 kt\u00f3rego mo\u017cemy zadeklarowa\u0107 na przyk\u0142ad parametr <em>Union[float, int] <\/em>obs\u0142uguj\u0105cy oba typy prymitywne. Je\u015bli wspierane s\u0105 zmienne ka\u017cdego typu, mo\u017cna to jawnie oznaczy\u0107 poprzez u\u017cycie <em>Any<\/em>.<\/p>\n\n\n\n<p>Ka\u017cda klasa zdefiniowana w naszym kodzie r\u00f3wnie\u017c mo\u017ce by\u0107 u\u017cyta w deklaracji typu.<\/p>\n\n\n\n<p>Nie wszystkie metody musz\u0105 zwr\u00f3ci\u0107 wynik \u2013 w takim wypadku mo\u017cna zwr\u00f3ci\u0107 warto\u015b\u0107 <em>Optional<\/em>(na przyk\u0142ad <em>Optional[str]<\/em>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Przyk\u0142ad u\u017cycia<\/strong><\/h2>\n\n\n\n<p>Za\u0142\u00f3\u017cmy, \u017ce chcemy stworzy\u0107 skrypt do klasyfikacji plik\u00f3w na podstawie ich rozszerzenia.<\/p>\n\n\n\n<p>Jedn\u0105 z funkcji kt\u00f3r\u0105 mogliby\u015bmy zdefiniowa\u0107 wygl\u0105da tak:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n```\ndef is_text_file(path):\n    return path.endswith(&quot;.txt&quot;)\n```\n<\/pre><\/div>\n\n\n<p>IDE (w moim przypadku Visual Studio Code) nie podpowie, co mog\u0119 zrobi\u0107 ze zmienn\u0105:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image1-1.png\"><img decoding=\"async\" width=\"765\" height=\"97\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image1-1.png\" alt=\"code\" class=\"wp-image-28412\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image1-1.png 765w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image1-1-300x38.png 300w\" sizes=\"(max-width: 765px) 100vw, 765px\" \/><\/a><\/figure>\n\n\n\n<p>U\u017cywaj\u0105c wskaz\u00f3wek typu, w tym wypadku dla argumentu oraz typu zwracanego, mo\u017cemy zmieni\u0107 kod na:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n```\ndef is_text_file(path: str) -&gt; bool:\n    return path.endswith(&quot;.txt&quot;)\n```\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image2-1.png\"><img decoding=\"async\" width=\"758\" height=\"397\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image2-1.png\" alt=\"code\" class=\"wp-image-28414\" style=\"object-fit:cover\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image2-1.png 758w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image2-1-300x157.png 300w\" sizes=\"(max-width: 758px) 100vw, 758px\" \/><\/a><\/figure>\n\n\n\n<p>IDE rozpoznaje teraz i podpowiada, co mo\u017cna zrobi\u0107 ze zmienn\u0105 typu <em>str<\/em>.<\/p>\n\n\n\n<p>IDE r\u00f3wnie\u017c podpowiada przy wywo\u0142aniach metody, je\u015bli chcemy skorzysta\u0107 z funkcji:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image3.png\"><img decoding=\"async\" width=\"767\" height=\"228\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image3.png\" alt=\"code\" class=\"wp-image-28416\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image3.png 767w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image3-300x89.png 300w\" sizes=\"(max-width: 767px) 100vw, 767px\" \/><\/a><\/figure>\n\n\n\n<p>Z biegiem czasu mo\u017ce przybywa\u0107 funkcjonalno\u015bci w skrypcie lub b\u0119dziemy chcieli listowa\u0107 pliki tekstowe z danego folderu. <\/p>\n\n\n\n<p>Zdefiniujemy wi\u0119c klas\u0119 <em>Directory<\/em>. Niech metoda inicjalizuj\u0105ca przyjmuje list\u0119 nazw plik\u00f3w, oznaczaj\u0105c to wskaz\u00f3wk\u0105 typu. W metodzie zwracaj\u0105cej list\u0119 plik\u00f3w tekstowych IDE jest w stanie wydedukowa\u0107, \u017ce iterowana jest lista, a jej pojedynczy element zosta\u0142 oznaczony jako <em>str<\/em>, wi\u0119c znowu prawid\u0142owo podpowie metod\u0119 <em>endswith<\/em>. Je\u015bli konstruktor nie b\u0119dzie zawiera\u0142 tej wskaz\u00f3wki, IDE nie b\u0119dzie w stanie nic podpowiedzie\u0107.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image4.png\"><img decoding=\"async\" width=\"1024\" height=\"499\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image4-1024x499.png\" alt=\"code\" class=\"wp-image-28418\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image4-1024x499.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image4-300x146.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image4-768x375.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/image4.png 1220w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>To s\u0105 najbardziej podstawowe u\u017cycia wskaz\u00f3wek typu, a ju\u017c w du\u017cej cz\u0119\u015bci umo\u017cliwiaj\u0105 prac\u0119 z kodem, jak przy j\u0119zykach ze statycznym typowaniem. Nawigacja w kodzie, posiadaj\u0105c ci\u0105gi wywo\u0142a\u0144 r\u00f3\u017cnych metod, b\u0119dzie z takim rozwi\u0105zaniem znacznie \u0142atwiejsza. Zamiast wyszukiwa\u0107 spodziewanego typu argumentu na podstawie jednego z wywo\u0142a\u0144 danej metody, od razu widoczny jest typ, kt\u00f3rego si\u0119 spodziewamy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Zmiany mi\u0119dzy wersjami<\/strong><\/h2>\n\n\n\n<p>Funkcjonalno\u015b\u0107 ta oczywi\u015bcie zmienia\u0142a si\u0119 mi\u0119dzy wersjami Pythona. Zmiany s\u0105 w przyst\u0119pny spos\u00f3b opisane w sekcjach \u201eWhat\u2019s new\u201d na oficjalnej stronie dokumentacji do tego j\u0119zyka, (<a href=\"https:\/\/docs.python.org\/3\/whatsnew\/3.5.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >przyk\u0142ad dla wersji 3.5<\/a>).<\/p>\n\n\n\n<p>Je\u015bli chodzi o aspekt type hinting, zmienia\u0142y si\u0119 mi\u0119dzy innymi nast\u0119puj\u0105ce rzeczy:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Python 3.7:\n<ul class=\"wp-block-list\">\n<li>poprawa wydajno\u015bci \u2013 czas importowania modu\u0142u <em>typing<\/em> zredukowany 7-krotnie,<\/li>\n\n\n\n<li>naprawa b\u0142\u0119d\u00f3w.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Python 3.8\n<ul class=\"wp-block-list\">\n<li>lepsze wsparcie dla s\u0142ownik\u00f3w (<em>dict<\/em>),<\/li>\n\n\n\n<li>wsparcie dla litera\u0142\u00f3w,<\/li>\n\n\n\n<li>wsparcie dla zmiennych finalnych (oznaczanych poprzez <em>Final<\/em>).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Python 3.9\n<ul class=\"wp-block-list\">\n<li>ulepszone wsparcie dla typ\u00f3w generycznych (list, zamiast List itd., dzi\u0119ki czemu nie jest ju\u017c potrzebne importowanie modu\u0142u typing),<\/li>\n\n\n\n<li>poprawki do litera\u0142\u00f3w.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Python 3.10\n<ul class=\"wp-block-list\">\n<li>wsparcie dla <em>Callable<\/em> oraz powi\u0105zanego z nim <a href=\"https:\/\/docs.python.org\/3\/library\/typing.html#typing.Concatenate\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" ><em>Concatenate<\/em><\/a>,<\/li>\n\n\n\n<li>mo\u017cliwo\u015b\u0107 u\u017cycia operatora \u201c|\u201d zamiast <em>Union,<\/em><\/li>\n\n\n\n<li>dodano \u201c<a href=\"https:\/\/docs.python.org\/3\/library\/typing.html#typing.TypeGuard\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >type guarding<\/a>\u201d, funkcje wspomagaj\u0105ce zaw\u0119\u017ca\u0107 typ zmiennej.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Python 3.11\n<ul class=\"wp-block-list\">\n<li>wsparcie dla self (w postaci <em>Self<\/em>).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Warto zaznaczy\u0107, \u017ce jest to jedynie cz\u0119\u015b\u0107 wprowadzonych zmian dla modu\u0142u <em>typing<\/em>. Wybra\u0142em te, kt\u00f3re moim zdaniem <strong>najcz\u0119\u015bciej b\u0119d\u0105 u\u017cywane przez u\u017cytkownik\u00f3w<\/strong>. Aby sprawdzi\u0107 wszystkie zmiany, warto zobaczy\u0107 wspomniane wcze\u015bniej sekcje \u201cWhat\u2019s new\u201d <a href=\"https:\/\/docs.python.org\/3\/whatsnew\/3.5.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >dokumentacji Pythona dla wersji 3.5 i wy\u017cej<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>Dodanie wskaz\u00f3wek typu do kodu w ma\u0142ym skrypcie mo\u017ce nie przynie\u015b\u0107 ogromnych korzy\u015bci. Jednak w \u015brednim, a tym bardziej wi\u0119kszym projekcie mo\u017ce znacznie <strong>u\u0142atwi\u0107 i przyspieszy\u0107 prac\u0119 w ca\u0142ym zespole bardzo ma\u0142ym kosztem.<\/strong><\/p>\n\n\n\n<p>Aby korzysta\u0107 z deklaracji typ\u00f3w, nie trzeba instalowa\u0107 dodatkowych bibliotek, a wi\u0119kszo\u015b\u0107 \u015brodowisk posiada ju\u017c wersj\u0119 Pythona wspieraj\u0105c\u0105 t\u0119 funkcjonalno\u015b\u0107. Co wi\u0119cej, do faktycznej walidacji czy kod u\u017cywany jest zgodnie z deklaracjami typu, mo\u017cna korzysta\u0107 z narz\u0119dzi typu \u201e<a href=\"https:\/\/docs.python.org\/3\/glossary.html#term-static-type-checker\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >static type checker<\/a>\u201d.<\/p>\n\n\n\n<p>Sama funkcjonalno\u015b\u0107 oznaczania typ\u00f3w w Pythonie jest rozwijana mi\u0119dzy innymi z my\u015bl\u0105 o narz\u0119dziach do statycznej analizy kodu, a jednym z nich jest stworzony przez Microsoft \u201c<a href=\"https:\/\/github.com\/microsoft\/pyright\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >pyright<\/a>\u201d, mo\u017cliwy do zainstalowania za pomoc\u0105 \u201cpip\u201d.<\/p>\n\n\n\n<p>Z takim zestawem narz\u0119dzi praca z kodem mo\u017ce by\u0107 znacznie u\u0142atwiona. A co najwa\u017cniejsze \u2013 wskaz\u00f3wki typu nie s\u0105 obowi\u0105zkowe i nie jest konieczne oznaczenie ca\u0142ego projektu. To rozwi\u0105zanie daje elastyczno\u015b\u0107 u\u017cytkownikowi. Krytyczna i wra\u017cliwa cz\u0119\u015b\u0107 kodu mo\u017ce posiada\u0107 wskaz\u00f3wki, a mniej istotne cz\u0119\u015bci mo\u017cna pomin\u0105\u0107, jak np.: oznaczanie typu <em>str<\/em> jako zwracanego z tak zwanej magicznej metody <em>__str__<\/em>. Takie podej\u015bcie pozwoli na <strong>zr\u00f3wnowa\u017cenie zysk\u00f3w<\/strong> p\u0142yn\u0105cych z u\u017cycia tej funkcjonalno\u015bci i czasu potrzebnego na jej wdro\u017cenie oraz utrzymanie.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;28411&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;6&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 6)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Type hints w j\u0119zyku Python&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 6)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>W pracy z kodem kluczowa jest jego dobra czytelno\u015b\u0107, a jawne deklarowanie typ\u00f3w zmiennych mo\u017ce znacznie w tym pom\u00f3c. To &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/type-hints-w-jezyku-python\/\">Continued<\/a><\/p>\n","protected":false},"author":653,"featured_media":28422,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[2234,1512,563,584],"class_list":["post-28411","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-type-hints","tag-poradnik","tag-embedded","tag-python"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/Type-hints-w-jezyku-Python.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/28411"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/653"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=28411"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/28411\/revisions"}],"predecessor-version":[{"id":28448,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/28411\/revisions\/28448"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/28422"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=28411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=28411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=28411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}