pyduck – biblioteka do interfejsów w Pythonie

2011-09-26 22:16

Czas pochwalić się swoim nowym dziełem. Nie jest ono bardzo imponujące ani specjalnie duże. Mam jednak nadzieję, że będzie ono przydatne dla tego (wąskiego) grona odbiorców, do którego jest skierowane.

Mam tu na myśli niewielką biblioteką do Pythona, która ma na celu poprawienie użyteczności jednej z głównych, ideowych cech języka – tak zwanego typowania kaczkowego (duck typing). Geneza tego terminu jest oczywiście wielce intrygująca, ale założenie jest proste. Zamiast czynić obietnice i jawnie deklarować implementowane interfejsy, obiekty w Pythonie “po prostu są” i zwykle próbują być od razu używane do założonych celów. Jeśli okażą się niekompatybilne (np. nie posiadają żądanej metody), wtedy oczywiście rzucany jest wyjątek. Pythonowska praktyka polega więc na przechodzeniu do rzeczy bez zbędnych ceregieli i obsłudze ewentualnych błędów.

Ma to rzecz jasna swoje zalety, ma też wady, a czasami może również rodzić problemy, jeśli błąd spowodowany niekompatybilnością obiektu ujawni się za późno. Z drugiej strony brak konieczności jawnego specyfikowania implementowanych interfejsów to spora zaleta. Najlepiej więc byłoby jakoś połączyć te dwa światy i umożliwić wcześniejsze sprawdzenie możliwości obiektu…

Jak można się pewnie domyślić, to właśnie próbuje umożliwić mój framework, noszący wdzięczną nazwę pyduck. Dodaje on do Pythona mechanizm interfejsów bardzo podobny do tego, który obecny jest w języku Go. Najważniejszą jego cechą jest właśnie fakt, że w konkretnych typach interfejsy są implementowane niejako automatycznie – wystarczy, że mają one odpowiednie metody. Samo sprawdzenie, czy obiekt implementuje dany interfejs polega zaś na faktycznym zaglądnięciu w listę jego metod, a nie weryfikacji jakichś jawnych deklaracji.

Inaczej mówiąc, nie czynimy tutaj żadnych obietnic odnośnie obiektu, ale wciąż mamy możliwość kontroli, czy nasze wymagania są spełnione. Najlepiej ilustruje to oczywiście konkretny przykład:

  1. from pyduck import Interface, expects
  2.  
  3. class Drawable(Interface):
  4.     def get_bounds(self): pass
  5.     def draw(self, canvas): pass
  6.  
  7. class Canvas(object):
  8.     @expects(Drawable)
  9.     def draw_object(self, obj):
  10.         bounds = obj.get_bounds()
  11.         self.set_clipping_bounds(bounds)
  12.         obj.draw(self)

Zaznaczamy w nim, że metoda Canvas.draw_object spodziewa się obiektu zgodnego z interfejsem Drawable. Jest on zdefiniowany wyżej jako posiadający metody get_bounds i draw. Sprawdzenie, czy rzeczywisty argument funkcji spełnia nasze wymogi, zostanie wykonane przez dekorator @expects. Zweryfikuje on obecność i sygnatury metod wspomnianych metod.
Dzięki temu będziemy mogli być pewni, że mamy do czynienia z obiektem, który rzeczywiście potrafi się narysować. Jego konkretna klasa nie będzie musiała natomiast nic wiedzieć na temat interfejsu Drawable ani jawnie deklarować jego wykorzystania.

Po więcej informacji zapraszam oczywiście na stronę projektu na GitHubie. Ewentualnie można też od razu zainstalować paczkę, np. poprzez easy_install:

  1. $ sudo easy_install pyduck

A ponieważ wszystko open source jest zawsze wersją rozwojową, nie muszę chyba wspominać, że z chęcią witam pull requesty z usprawnieniami i poprawkami :>

Tags: , , , ,
Author: Xion, posted under Programming »


One comment for post “pyduck – biblioteka do interfejsów w Pythonie”.
  1. sunprog:
    March 20th, 2012 o 18:12

    “(…) czasami może również rodzić problemy, jeśli błąd spowodowany niekompatybilnością obiektu ujawni się za późno.”

    Czy mógłbyś przedstawić sytuacje dla których wspomniana niekompatybilność ujawnia się za późno oraz czy mógłbyś przedstawić w jaki sposób obsługiwałbyś rzucony wyjątek przez swój framework?

    Bardzo mnie to zastanawia, bo przecież jeśli konkretny obiekt nie będzie posiadał zadanej metody to zostanie rzucony standardowy wyjątek. Tu przecież wina leżeć będzie po stronie programisty, a zatem trudno jest mi myśleć o jakimś rozsądnym rozwiązaniu poza przerwaniem aplikacji. No może to ma jakiś sens dla softu, który musi cały czas trzymać się na nogach, ale czy wtedy nie lepiej po prostu byłoby wylapywac wszystkie exceptiony do jednego worka i tam sie z nimi rozprawiać?

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.