{"id":1488,"date":"2026-04-05T13:33:04","date_gmt":"2026-04-05T11:33:04","guid":{"rendered":"https:\/\/trzykody.pl\/?p=1488"},"modified":"2026-04-25T13:37:51","modified_gmt":"2026-04-25T11:37:51","slug":"issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy","status":"publish","type":"post","link":"https:\/\/trzykody.pl\/index.php\/2026\/04\/05\/issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy\/","title":{"rendered":"Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy."},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Programowanie obiektowe szybko przestaje by\u0107 wygodne, je\u015bli w kodzie nie kontroluje si\u0119 relacji mi\u0119dzy klasami. Dziedziczenie pomaga budowa\u0107 hierarchie typ\u00f3w, ale r\u00f3wnie wa\u017cne jest sprawdzenie, czy dana klasa rzeczywi\u015bcie nale\u017cy do oczekiwanej ga\u0142\u0119zi. Bez tego \u0142atwo dopu\u015bci\u0107 do b\u0142\u0119d\u00f3w w walidacji danych, niepoprawnego dzia\u0142ania fabryk obiekt\u00f3w albo \u017ale napisanych mechanizm\u00f3w plugin\u00f3w. W codziennej pracy z dziedziczeniem szczeg\u00f3lnie przydaje si\u0119 Issubclass.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Spis Tre\u015bci<\/h2><nav><ol><li><a href=\"#kiedy-issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy-i-dlaczego-to-wazne-przy-projektowaniu-hierarchii\">Kiedy Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy i dlaczego to wa\u017cne przy projektowaniu hierarchii<\/a><\/li><li><a href=\"#mechanizm-dziedziczenia-i-relacja-miedzy-typem-a-instancja\">Mechanizm dziedziczenia i relacja mi\u0119dzy typem a instancj\u0105<\/a><\/li><li><a href=\"#jak-dziala-issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy-na-poziomie-interpretera-pythona\">Jak dzia\u0142a Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy na poziomie interpretera Pythona<\/a><\/li><li><a href=\"#odpowiedniki-tego-podejscia-w-c-c-i-roznice-praktyczne\">Odpowiedniki tego podej\u015bcia w C, C++ i r\u00f3\u017cnice praktyczne<\/a><ol><li><a href=\"#c\">C++<\/a><\/li><li><a href=\"#c-1\">C<\/a><\/li><li><a href=\"#python\">Python<\/a><\/li><\/ol><\/li><li><a href=\"#zastosowanie-w-fabrykach-obiektow-systemach-pluginow-i-walidacji-architektury\">Zastosowanie w fabrykach obiekt\u00f3w, systemach plugin\u00f3w i walidacji architektury<\/a><\/li><li><a href=\"#typowe-bledy-pulapki-i-sytuacje-graniczne-gdy-issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy\">Typowe b\u0142\u0119dy, pu\u0142apki i sytuacje graniczne gdy Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy<\/a><ol><li><a href=\"#przekazanie-obiektu-zamiast-klasy\">Przekazanie obiektu zamiast klasy<\/a><\/li><li><a href=\"#zapominanie-o-dziedziczeniu-posrednim\">Zapominanie o dziedziczeniu po\u015brednim<\/a><\/li><li><a href=\"#dziedziczenie-wielokrotne\">Dziedziczenie wielokrotne<\/a><\/li><\/ol><\/li><li><a href=\"#krotkie-uwagi-praktyczne-przy-pracy-z-duzym-kodem\">Kr\u00f3tkie uwagi praktyczne przy pracy z du\u017cym kodem<\/a><\/li><li><a href=\"#faq\">FAQ<\/a><ol><li><a href=\"#czy-issubclass-dziala-na-obiektach\">Czy issubclass() dzia\u0142a na obiektach?<\/a><\/li><li><a href=\"#czy-klasa-jest-podklasa-samej-siebie\">Czy klasa jest podklas\u0105 samej siebie?<\/a><\/li><li><a href=\"#czy-mozna-sprawdzic-kilka-klas-naraz\">Czy mo\u017cna sprawdzi\u0107 kilka klas naraz?<\/a><\/li><li><a href=\"#dlaczego-issubclass-bool-int-zwraca-true\">Dlaczego issubclass(bool, int) zwraca True?<\/a><\/li><li><a href=\"#czy-ta-funkcja-dziala-szybko\">Czy ta funkcja dzia\u0142a szybko?<\/a><\/li><li><a href=\"#czy-w-c-istnieje-odpowiednik\">Czy w C istnieje odpowiednik?<\/a><\/li><\/ol><\/li><\/ol><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"kiedy-issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy-i-dlaczego-to-wazne-przy-projektowaniu-hierarchii\">Kiedy Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy i dlaczego to wa\u017cne przy projektowaniu hierarchii<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Funkcja <code>issubclass()<\/code> jest wbudowan\u0105 funkcj\u0105 Pythona s\u0142u\u017c\u0105c\u0105 do sprawdzania relacji dziedziczenia pomi\u0119dzy klasami. Zwraca warto\u015b\u0107 logiczn\u0105 <code>True<\/code> albo <code>False<\/code>, dzi\u0119ki czemu mo\u017cna szybko zweryfikowa\u0107, czy jedna klasa dziedziczy po drugiej &#8211; bez r\u0119cznego analizowania kodu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sk\u0142adnia jest prosta:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Element<\/th><th>Opis<\/th><\/tr><\/thead><tbody><tr><td><code>issubclass(A, B)<\/code><\/td><td>sprawdza, czy klasa <code>A<\/code> dziedziczy po klasie <code>B<\/code><\/td><\/tr><tr><td>wynik <code>True<\/code><\/td><td><code>A<\/code> jest klas\u0105 potomn\u0105 <code>B<\/code> lub jest dok\u0142adnie klas\u0105 <code>B<\/code><\/td><\/tr><tr><td>wynik <code>False<\/code><\/td><td>brak relacji dziedziczenia<\/td><\/tr><tr><td>wyj\u0105tek <code>TypeError<\/code><\/td><td>pierwszy argument nie jest klas\u0105<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To ostatnie bywa pomijane. <code>issubclass()<\/code> dzia\u0142a na klasach, nie na obiektach. Je\u015bli kto\u015b przeka\u017ce instancj\u0119 zamiast typu, program zako\u0144czy si\u0119 wyj\u0105tkiem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>podstawowe sprawdzenie<\/td><td><code>class Zwierze: pass<\/code><br><code>class Pies(Zwierze): pass<\/code><br><code>print(issubclass(Pies, Zwierze))<\/code><br><code># True<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">W wi\u0119kszych systemach to ma realne znaczenie. Przyk\u0142ad praktyczny: system importuj\u0105cy r\u00f3\u017cne typy dokument\u00f3w mo\u017ce wymaga\u0107, aby ka\u017cda nowa klasa dziedziczy\u0142a po wsp\u00f3lnej klasie <code>BaseImporter<\/code>. Zamiast ufa\u0107 programi\u015bcie, kod mo\u017ce to sprawdzi\u0107 automatycznie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Brak takiej kontroli cz\u0119sto ko\u0144czy si\u0119 strat\u0105 czasu: b\u0142\u0119dy pojawiaj\u0105 si\u0119 p\u00f3\u017ano, zwykle dopiero w produkcji.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"mechanizm-dziedziczenia-i-relacja-miedzy-typem-a-instancja\">Mechanizm dziedziczenia i relacja mi\u0119dzy typem a instancj\u0105<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Najcz\u0119stszy b\u0142\u0105d pocz\u0105tkuj\u0105cych to mylenie <code>issubclass()<\/code> z <code>isinstance()<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To s\u0105 dwa r\u00f3\u017cne narz\u0119dzia:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Funkcja<\/th><th>Sprawdza<\/th><th>Przyk\u0142ad<\/th><\/tr><\/thead><tbody><tr><td><code>issubclass()<\/code><\/td><td>relacj\u0119 klasa \u2192 klasa<\/td><td>czy <code>Pies<\/code> dziedziczy po <code>Zwierze<\/code><\/td><\/tr><tr><td><code>isinstance()<\/code><\/td><td>relacj\u0119 obiekt \u2192 klasa<\/td><td>czy <code>reksio<\/code> jest obiektem typu <code>Zwierze<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad por\u00f3wnania:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>por\u00f3wnanie funkcji<\/td><td><code>class Zwierze: pass<\/code><br><code>class Pies(Zwierze): pass<\/code><br><code>reksio = Pies()<\/code><br><br><code>print(issubclass(Pies, Zwierze))<\/code><br><code>print(isinstance(reksio, Zwierze))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Obie instrukcje zwr\u00f3c\u0105 <code>True<\/code>, ale badaj\u0105 co\u015b innego.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W praktyce:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>issubclass()<\/code> u\u017cywa si\u0119 przy analizie architektury programu<\/li>\n\n\n\n<li><code>isinstance()<\/code> u\u017cywa si\u0119 podczas pracy na obiektach<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u015bli piszesz system rejestruj\u0105cy klasy plugin\u00f3w, potrzebujesz pierwszej funkcji. Je\u015bli walidujesz dane wej\u015bciowe u\u017cytkownika, cz\u0119\u015bciej potrzebujesz drugiej.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"jak-dziala-issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy-na-poziomie-interpretera-pythona\">Jak dzia\u0142a Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy na poziomie interpretera Pythona<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Python przechowuje informacj\u0119 o dziedziczeniu w atrybucie <code>__mro__<\/code> (Method Resolution Order). To uporz\u0105dkowana lista klas, po kt\u00f3rych interpreter szuka metod.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dla klasy:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>MRO<\/td><td><code>class A: pass<\/code><br><code>class B(A): pass<\/code><br><code>print(B.__mro__)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">wynik b\u0119dzie podobny do:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Wynik<\/th><th>Warto\u015b\u0107<\/th><\/tr><\/thead><tbody><tr><td><code>__mro__<\/code><\/td><td><code>(&lt;class 'B'&gt;, &lt;class 'A'&gt;, &lt;class 'object'&gt;)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><code>issubclass()<\/code> analizuje w\u0142a\u015bnie t\u0119 struktur\u0119. Je\u015bli klasa bazowa znajduje si\u0119 w \u015bcie\u017cce dziedziczenia, wynik b\u0119dzie dodatni.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Istotne jest te\u017c to, \u017ce mo\u017cna sprawdza\u0107 wiele klas naraz:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>krotka klas<\/td><td><code>print(issubclass(Pies, (Zwierze, object)))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To jest bardzo wygodne w walidatorach i systemach dynamicznego \u0142adowania modu\u0142\u00f3w.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dodatkowo:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Zachowanie<\/th><th>Wynik<\/th><\/tr><\/thead><tbody><tr><td><code>issubclass(A, A)<\/code><\/td><td><code>True<\/code><\/td><\/tr><tr><td><code>issubclass(bool, int)<\/code><\/td><td><code>True<\/code><\/td><\/tr><tr><td><code>issubclass(list, object)<\/code><\/td><td><code>True<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Szczeg\u00f3lnie <code>bool<\/code> i <code>int<\/code> zaskakuje wiele os\u00f3b. W Pythonie <code>bool<\/code> dziedziczy po <code>int<\/code>, dlatego:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>ciekawy przypadek<\/td><td><code>print(issubclass(bool, int))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">zwraca <code>True<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To nie jest b\u0142\u0105d &#8211; to decyzja projektowa j\u0119zyka.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"odpowiedniki-tego-podejscia-w-c-c-i-roznice-praktyczne\">Odpowiedniki tego podej\u015bcia w C, C++ i r\u00f3\u017cnice praktyczne<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Python ma wbudowane narz\u0119dzie, ale inne j\u0119zyki rozwi\u0105zuj\u0105 to inaczej.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"c\">C++<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">W C++ mo\u017cna u\u017cy\u0107 <code>std::is_base_of<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>C++<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>sprawdzenie relacji typ\u00f3w<\/td><td><code>#include &lt;iostream&gt;<\/code><br><code>#include &lt;type_traits&gt;<\/code><br><br><code>class Zwierze {};<\/code><br><code>class Pies : public Zwierze {};<\/code><br><br><code>int main() {<\/code><br><code>std::cout &lt;&lt; std::is_base_of&lt;Zwierze, Pies&gt;::value;<\/code><br><code>}<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Tutaj wynik jest obliczany na etapie kompilacji, nie dzia\u0142ania programu.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"c-1\">C<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">C nie ma natywnego dziedziczenia klas, wi\u0119c podobny mechanizm trzeba budowa\u0107 r\u0119cznie.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>C<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>kontrola typu przez znacznik<\/td><td><code>struct Zwierze { int typ; };<\/code><br><code>struct Pies { int typ; };<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To rozwi\u0105zanie jest znacznie mniej bezpieczne i wymaga dyscypliny programisty.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"python\">Python<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>sprawdzenie w runtime<\/td><td><code>print(issubclass(Pies, Zwierze))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Python daje tutaj najwi\u0119ksz\u0105 wygod\u0119, ale wymaga ostro\u017cno\u015bci przy dynamicznym typowaniu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"zastosowanie-w-fabrykach-obiektow-systemach-pluginow-i-walidacji-architektury\">Zastosowanie w fabrykach obiekt\u00f3w, systemach plugin\u00f3w i walidacji architektury<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Najbardziej praktyczne u\u017cycie pojawia si\u0119 tam, gdzie klasy s\u0105 rejestrowane dynamicznie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad: system raport\u00f3w.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ka\u017cdy raport musi dziedziczy\u0107 po <code>BaseReport<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>walidacja klasy<\/td><td><code>class BaseReport: pass<\/code><br><br><code>def register(cls):<\/code><br><code>if not issubclass(cls, BaseReport):<\/code><br><code>raise TypeError(\"Niepoprawny typ klasy\")<\/code><br><code>print(\"Zarejestrowano\")<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Bez tego mo\u017cna przypadkowo zarejestrowa\u0107 klas\u0119, kt\u00f3ra nie implementuje wymaganych metod.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Podobnie dzia\u0142a wiele framework\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>systemy ORM<\/li>\n\n\n\n<li>generatory formularzy<\/li>\n\n\n\n<li>biblioteki testowe<\/li>\n\n\n\n<li>mechanizmy serializer\u00f3w<\/li>\n\n\n\n<li>systemy event-driven<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Program wygl\u0105da wtedy stabilniej, bo b\u0142\u0119dy wychodz\u0105 wcze\u015bniej.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To wa\u017cne finansowo i organizacyjnie &#8211; b\u0142\u0105d wykryty podczas rejestracji klasy kosztuje minuty, a ten sam b\u0142\u0105d wykryty po wdro\u017ceniu potrafi kosztowa\u0107 godziny pracy zespo\u0142u.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"typowe-bledy-pulapki-i-sytuacje-graniczne-gdy-issubclass-sprawdza-czy-klasa-jest-podklasa-innej-klasy\">Typowe b\u0142\u0119dy, pu\u0142apki i sytuacje graniczne gdy Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Najcz\u0119stsze problemy s\u0105 bardzo powtarzalne.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"przekazanie-obiektu-zamiast-klasy\">Przekazanie obiektu zamiast klasy<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>B\u0142\u0105d<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>niepoprawnie<\/td><td><code>reksio = Pies()<\/code><br><code>issubclass(reksio, Zwierze)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To zako\u0144czy si\u0119 <code>TypeError<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Poprawnie:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Poprawnie<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>w\u0142a\u015bciwe u\u017cycie<\/td><td><code>issubclass(Pies, Zwierze)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"zapominanie-o-dziedziczeniu-posrednim\">Zapominanie o dziedziczeniu po\u015brednim<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Przyk\u0142ad<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>dziedziczenie wielopoziomowe<\/td><td><code>class A: pass<\/code><br><code>class B(A): pass<\/code><br><code>class C(B): pass<\/code><br><code>print(issubclass(C, A))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wynik to <code>True<\/code>, mimo \u017ce <code>C<\/code> nie dziedziczy bezpo\u015brednio po <code>A<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"dziedziczenie-wielokrotne\">Dziedziczenie wielokrotne<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Python<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>wiele klas bazowych<\/td><td><code>class A: pass<\/code><br><code>class B: pass<\/code><br><code>class C(A, B): pass<\/code><br><code>print(issubclass(C, B))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wynik r\u00f3wnie\u017c b\u0119dzie <code>True<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To ma znaczenie przy projektowaniu du\u017cych system\u00f3w &#8211; \u0142atwo przypadkiem uzyska\u0107 relacj\u0119, kt\u00f3rej nikt nie planowa\u0142.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"krotkie-uwagi-praktyczne-przy-pracy-z-duzym-kodem\">Kr\u00f3tkie uwagi praktyczne przy pracy z du\u017cym kodem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Nie warto u\u017cywa\u0107 tej funkcji wsz\u0119dzie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dobre miejsca:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>rejestracja klas<\/li>\n\n\n\n<li>walidacja plugin\u00f3w<\/li>\n\n\n\n<li>frameworki wewn\u0119trzne<\/li>\n\n\n\n<li>kontrola architektury<\/li>\n\n\n\n<li>testy jednostkowe<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">S\u0142abe miejsca:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>zwyk\u0142a logika biznesowa<\/li>\n\n\n\n<li>kod wykonywany bardzo cz\u0119sto w p\u0119tli<\/li>\n\n\n\n<li>miejsca, gdzie wystarczy <code>isinstance()<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Warto te\u017c pami\u0119ta\u0107, \u017ce nadmierne poleganie na dziedziczeniu samo w sobie bywa problemem. Czasem lepsza jest kompozycja ni\u017c rozbudowane drzewo klas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u017celi hierarchia ma 7\u20138 poziom\u00f3w, zwykle problem nie le\u017cy w braku <code>issubclass()<\/code>, tylko w z\u0142ym projekcie modelu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-issubclass-dziala-na-obiektach\">Czy <code>issubclass()<\/code> dzia\u0142a na obiektach?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nie. Funkcja oczekuje klas jako argument\u00f3w. Dla obiekt\u00f3w nale\u017cy u\u017cy\u0107 <code>isinstance()<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-klasa-jest-podklasa-samej-siebie\">Czy klasa jest podklas\u0105 samej siebie?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tak. <code>issubclass(A, A)<\/code> zwraca <code>True<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-mozna-sprawdzic-kilka-klas-naraz\">Czy mo\u017cna sprawdzi\u0107 kilka klas naraz?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tak. Drugi argument mo\u017ce by\u0107 krotk\u0105 klas, na przyk\u0142ad <code>issubclass(Pies, (Zwierze, object))<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"dlaczego-issubclass-bool-int-zwraca-true\">Dlaczego <code>issubclass(bool, int)<\/code> zwraca <code>True<\/code>?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Poniewa\u017c w Pythonie <code>bool<\/code> dziedziczy po <code>int<\/code>. To zachowanie jest zgodne ze specyfikacj\u0105 j\u0119zyka.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-ta-funkcja-dziala-szybko\">Czy ta funkcja dzia\u0142a szybko?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tak, dla normalnych zastosowa\u0144 koszt jest niewielki. Nie nale\u017cy jednak u\u017cywa\u0107 jej bez potrzeby w bardzo intensywnych p\u0119tlach.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-w-c-istnieje-odpowiednik\">Czy w C istnieje odpowiednik?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nie wprost. C nie posiada klas ani dziedziczenia obiektowego w standardowym znaczeniu, wi\u0119c podobne mechanizmy trzeba implementowa\u0107 r\u0119cznie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Relacja mi\u0119dzy klasami to jedna z tych rzeczy, kt\u00f3re wydaj\u0105 si\u0119 drobne, dop\u00f3ki system nie uro\u015bnie. Wtedy brak kontroli zaczyna kosztowa\u0107 realny czas. <code>issubclass()<\/code> jest prostym narz\u0119dziem, ale dobrze u\u017cyte porz\u0105dkuje architektur\u0119 i pozwala wykrywa\u0107 b\u0142\u0119dy zanim stan\u0105 si\u0119 problemem operacyjnym.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>\u0179r\u00f3d\u0142o Foto: Freepik<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Programowanie obiektowe szybko przestaje by\u0107 wygodne, je\u015bli w kodzie nie kontroluje si\u0119 relacji mi\u0119dzy klasami. Dziedziczenie pomaga budowa\u0107 hierarchie typ\u00f3w, ale r\u00f3wnie wa\u017cne jest sprawdzenie, czy dana klasa rzeczywi\u015bcie nale\u017cy do oczekiwanej ga\u0142\u0119zi. Bez tego \u0142atwo dopu\u015bci\u0107 do b\u0142\u0119d\u00f3w w walidacji danych, niepoprawnego dzia\u0142ania fabryk obiekt\u00f3w albo \u017ale napisanych mechanizm\u00f3w plugin\u00f3w. W codziennej pracy z dziedziczeniem szczeg\u00f3lnie przydaje si\u0119 Issubclass. Kiedy Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy i dlaczego to wa\u017cne przy projektowaniu hierarchii Funkcja issubclass() jest wbudowan\u0105 funkcj\u0105 Pythona s\u0142u\u017c\u0105c\u0105 do sprawdzania relacji dziedziczenia pomi\u0119dzy klasami. Zwraca warto\u015b\u0107 logiczn\u0105 True albo False, dzi\u0119ki czemu mo\u017cna szybko zweryfikowa\u0107, czy jedna klasa dziedziczy po drugiej &#8211; bez r\u0119cznego analizowania kodu. Sk\u0142adnia jest prosta: Element Opis issubclass(A, B) sprawdza, czy klasa A dziedziczy po klasie B wynik True A jest klas\u0105 potomn\u0105 B lub jest dok\u0142adnie klas\u0105 B wynik False brak relacji dziedziczenia wyj\u0105tek TypeError pierwszy argument nie jest klas\u0105 To ostatnie bywa pomijane. issubclass() dzia\u0142a na klasach, nie na obiektach. Je\u015bli kto\u015b przeka\u017ce instancj\u0119 zamiast typu, program zako\u0144czy si\u0119 wyj\u0105tkiem. Przyk\u0142ad: Python Kod podstawowe sprawdzenie class Zwierze: passclass Pies(Zwierze): passprint(issubclass(Pies, Zwierze))# True W wi\u0119kszych systemach to ma realne znaczenie. Przyk\u0142ad praktyczny: system importuj\u0105cy r\u00f3\u017cne typy dokument\u00f3w mo\u017ce wymaga\u0107, aby ka\u017cda nowa klasa dziedziczy\u0142a po wsp\u00f3lnej klasie BaseImporter. Zamiast ufa\u0107 programi\u015bcie, kod mo\u017ce to sprawdzi\u0107 automatycznie. Brak takiej kontroli cz\u0119sto ko\u0144czy si\u0119 strat\u0105 czasu: b\u0142\u0119dy pojawiaj\u0105 si\u0119 p\u00f3\u017ano, zwykle dopiero w produkcji. Mechanizm dziedziczenia i relacja mi\u0119dzy typem a instancj\u0105 Najcz\u0119stszy b\u0142\u0105d pocz\u0105tkuj\u0105cych to mylenie issubclass() z isinstance(). To s\u0105 dwa r\u00f3\u017cne narz\u0119dzia: Funkcja Sprawdza Przyk\u0142ad issubclass() relacj\u0119 klasa \u2192 klasa czy Pies dziedziczy po Zwierze isinstance() relacj\u0119 obiekt \u2192 klasa czy reksio jest obiektem typu Zwierze Przyk\u0142ad por\u00f3wnania: Python Kod por\u00f3wnanie funkcji class Zwierze: passclass Pies(Zwierze): passreksio = Pies() print(issubclass(Pies, Zwierze))print(isinstance(reksio, Zwierze)) Obie instrukcje zwr\u00f3c\u0105 True, ale badaj\u0105 co\u015b innego. W praktyce: Je\u015bli piszesz system rejestruj\u0105cy klasy plugin\u00f3w, potrzebujesz pierwszej funkcji. Je\u015bli walidujesz dane wej\u015bciowe u\u017cytkownika, cz\u0119\u015bciej potrzebujesz drugiej. Jak dzia\u0142a Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy na poziomie interpretera Pythona Python przechowuje informacj\u0119 o dziedziczeniu w atrybucie __mro__ (Method Resolution Order). To uporz\u0105dkowana lista klas, po kt\u00f3rych interpreter szuka metod. Dla klasy: Python Kod MRO class A: passclass B(A): passprint(B.__mro__) wynik b\u0119dzie podobny do: Wynik Warto\u015b\u0107 __mro__ (&lt;class 'B&#8217;&gt;, &lt;class 'A&#8217;&gt;, &lt;class 'object&#8217;&gt;) issubclass() analizuje w\u0142a\u015bnie t\u0119 struktur\u0119. Je\u015bli klasa bazowa znajduje si\u0119 w \u015bcie\u017cce dziedziczenia, wynik b\u0119dzie dodatni. Istotne jest te\u017c to, \u017ce mo\u017cna sprawdza\u0107 wiele klas naraz: Python Kod krotka klas print(issubclass(Pies, (Zwierze, object))) To jest bardzo wygodne w walidatorach i systemach dynamicznego \u0142adowania modu\u0142\u00f3w. Dodatkowo: Zachowanie Wynik issubclass(A, A) True issubclass(bool, int) True issubclass(list, object) True Szczeg\u00f3lnie bool i int zaskakuje wiele os\u00f3b. W Pythonie bool dziedziczy po int, dlatego: Python Kod ciekawy przypadek print(issubclass(bool, int)) zwraca True. To nie jest b\u0142\u0105d &#8211; to decyzja projektowa j\u0119zyka. Odpowiedniki tego podej\u015bcia w C, C++ i r\u00f3\u017cnice praktyczne Python ma wbudowane narz\u0119dzie, ale inne j\u0119zyki rozwi\u0105zuj\u0105 to inaczej. C++ W C++ mo\u017cna u\u017cy\u0107 std::is_base_of. C++ Kod sprawdzenie relacji typ\u00f3w #include &lt;iostream&gt;#include &lt;type_traits&gt; class Zwierze {};class Pies : public Zwierze {}; int main() {std::cout &lt;&lt; std::is_base_of&lt;Zwierze, Pies&gt;::value;} Tutaj wynik jest obliczany na etapie kompilacji, nie dzia\u0142ania programu. C C nie ma natywnego dziedziczenia klas, wi\u0119c podobny mechanizm trzeba budowa\u0107 r\u0119cznie. C Kod kontrola typu przez znacznik struct Zwierze { int typ; };struct Pies { int typ; }; To rozwi\u0105zanie jest znacznie mniej bezpieczne i wymaga dyscypliny programisty. Python Python Kod sprawdzenie w runtime print(issubclass(Pies, Zwierze)) Python daje tutaj najwi\u0119ksz\u0105 wygod\u0119, ale wymaga ostro\u017cno\u015bci przy dynamicznym typowaniu. Zastosowanie w fabrykach obiekt\u00f3w, systemach plugin\u00f3w i walidacji architektury Najbardziej praktyczne u\u017cycie pojawia si\u0119 tam, gdzie klasy s\u0105 rejestrowane dynamicznie. Przyk\u0142ad: system raport\u00f3w. Ka\u017cdy raport musi dziedziczy\u0107 po BaseReport. Python Kod walidacja klasy class BaseReport: pass def register(cls):if not issubclass(cls, BaseReport):raise TypeError(&#8222;Niepoprawny typ klasy&#8221;)print(&#8222;Zarejestrowano&#8221;) Bez tego mo\u017cna przypadkowo zarejestrowa\u0107 klas\u0119, kt\u00f3ra nie implementuje wymaganych metod. Podobnie dzia\u0142a wiele framework\u00f3w: Program wygl\u0105da wtedy stabilniej, bo b\u0142\u0119dy wychodz\u0105 wcze\u015bniej. To wa\u017cne finansowo i organizacyjnie &#8211; b\u0142\u0105d wykryty podczas rejestracji klasy kosztuje minuty, a ten sam b\u0142\u0105d wykryty po wdro\u017ceniu potrafi kosztowa\u0107 godziny pracy zespo\u0142u. Typowe b\u0142\u0119dy, pu\u0142apki i sytuacje graniczne gdy Issubclass \u2013 sprawdza, czy klasa jest podklas\u0105 innej klasy Najcz\u0119stsze problemy s\u0105 bardzo powtarzalne. Przekazanie obiektu zamiast klasy B\u0142\u0105d Kod niepoprawnie reksio = Pies()issubclass(reksio, Zwierze) To zako\u0144czy si\u0119 TypeError. Poprawnie: Poprawnie Kod w\u0142a\u015bciwe u\u017cycie issubclass(Pies, Zwierze) Zapominanie o dziedziczeniu po\u015brednim Przyk\u0142ad Kod dziedziczenie wielopoziomowe class A: passclass B(A): passclass C(B): passprint(issubclass(C, A)) Wynik to True, mimo \u017ce C nie dziedziczy bezpo\u015brednio po A. Dziedziczenie wielokrotne Python Kod wiele klas bazowych class A: passclass B: passclass C(A, B): passprint(issubclass(C, B)) Wynik r\u00f3wnie\u017c b\u0119dzie True. To ma znaczenie przy projektowaniu du\u017cych system\u00f3w &#8211; \u0142atwo przypadkiem uzyska\u0107 relacj\u0119, kt\u00f3rej nikt nie planowa\u0142. Kr\u00f3tkie uwagi praktyczne przy pracy z du\u017cym kodem Nie warto u\u017cywa\u0107 tej funkcji wsz\u0119dzie. Dobre miejsca: S\u0142abe miejsca: Warto te\u017c pami\u0119ta\u0107, \u017ce nadmierne poleganie na dziedziczeniu samo w sobie bywa problemem. Czasem lepsza jest kompozycja ni\u017c rozbudowane drzewo klas. Je\u017celi hierarchia ma 7\u20138 poziom\u00f3w, zwykle problem nie le\u017cy w braku issubclass(), tylko w z\u0142ym projekcie modelu. FAQ Czy issubclass() dzia\u0142a na obiektach? Nie. Funkcja oczekuje klas jako argument\u00f3w. Dla obiekt\u00f3w nale\u017cy u\u017cy\u0107 isinstance(). Czy klasa jest podklas\u0105 samej siebie? Tak. issubclass(A, A) zwraca True. Czy mo\u017cna sprawdzi\u0107 kilka klas naraz? Tak. Drugi argument mo\u017ce by\u0107 krotk\u0105 klas, na przyk\u0142ad issubclass(Pies, (Zwierze, object)). Dlaczego issubclass(bool, int) zwraca True? Poniewa\u017c w Pythonie bool dziedziczy po int. To zachowanie jest zgodne ze specyfikacj\u0105 j\u0119zyka. Czy ta funkcja dzia\u0142a szybko? Tak, dla normalnych zastosowa\u0144 koszt jest niewielki. Nie nale\u017cy jednak u\u017cywa\u0107 jej bez potrzeby w bardzo intensywnych p\u0119tlach. Czy w C istnieje odpowiednik? Nie wprost. C nie posiada klas ani dziedziczenia obiektowego w standardowym znaczeniu, wi\u0119c podobne mechanizmy trzeba implementowa\u0107 r\u0119cznie. Relacja mi\u0119dzy klasami to jedna z tych rzeczy, kt\u00f3re wydaj\u0105 si\u0119 drobne, dop\u00f3ki system nie uro\u015bnie. Wtedy brak kontroli zaczyna kosztowa\u0107 realny czas. issubclass() jest prostym narz\u0119dziem, ale dobrze u\u017cyte porz\u0105dkuje architektur\u0119 i pozwala wykrywa\u0107 b\u0142\u0119dy zanim stan\u0105 si\u0119 problemem operacyjnym. \u0179r\u00f3d\u0142o Foto: Freepik<\/p>\n","protected":false},"author":1,"featured_media":1489,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[],"class_list":["post-1488","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-jezyk-programowania"],"_links":{"self":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1488","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/comments?post=1488"}],"version-history":[{"count":1,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1488\/revisions"}],"predecessor-version":[{"id":1490,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1488\/revisions\/1490"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media\/1489"}],"wp:attachment":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media?parent=1488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/categories?post=1488"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/tags?post=1488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}