Garść pythonowych tipsów

Python Idioms and Efficiency 8/4/03

Reklamy

Znalezione na PubSub…

Pisałem już o swoich eksperymentach z PubSub. Zauważyłem, że jeden tytuł ciągle się
w powiadomieniach przewijał (z różnych źródeł): Python Is Not Java. W pewnym momencie dostałem
to nawet cyrylicą. W sumie to interesujące jak się informacja rozchodzi po różnych blogach itp.
W końcu postanowiłem zajrzeć o co chodzi i chyba znalazłem źródło: Python Is Not Java. Rzeczywiście
— ciekawy artykuł. Nie używam, ani za bardzo nie znam Javy, ale miło
poczytać chociażby o przewadze Pythona w niektórych dziedzinach
:-).

Zauważyłem też, że PubSub daleko do śledzenia całego Internetu, a może nawet
oni filtrują (cenzurują, jeśli ktoś woli) częściowo swoje feedy. Utworzyłem sobie subskrypcję która
miała wyłapywać różne erotyczne artykuły (taki eksperyment), ale nic takiego
się nie złapało (chociaż trafień zapytanie trochę miało). Możliwe też, że po
prostu brak feedów RSS dla takich mało ambitnych treści. BTW. wpisywanie zapytania fuck
ma mały sens — w końcu to wildcard do którego wszelkie tematy pasują ;-)

pub-sub

Ostatnio na Joggerze dużo się pisze o RSS, jak to wygodnie przeglądać w
ten sposób newsy z różnych źródeł. Ale to przecież dalekie od ideału… Po
pierwsze i tak trzeba znać źródła informacji którą się chce uzyskać, po drugie
oprogramowanie musi co chwilę sprawdzać, czy nowa informacja się pojawiła.
Pojawia się więc myśl, że fajnie by było jakbyśmy byli informowani jak
oczekiwana przez nas informacja się gdzieś pojawi.

Właśnie podczas czytania jednego z takich wpisów o RSS przypomniałem sobie
o pubsub. I mam na myśli właściwie dwie rzeczy. Jedna to protokół
pubsub
rozszerzenie XMPP rozwijane przez JSF (możliwe, że opowiem o tym na
najbliższych Pingwinariach), drugie to PubSub.com serwis pozwalający subskrybować
informacje jakie nas interesują, niezależnie od źródła. Zresztą, PubSub.com wykorzystuje technologię pubsub dla XMPP.

Jak sobie przypomniałem, że coś takiego istnieje, to postanowiłem
spróbować. Okazało się to prostrze niż mogłem przypuszczać. Po prostu
wystarczy wejść na stronę PubSub.com
i wpisać swoje zapytanie (podobnie jak do wyszukiwarki internetowej), a
następnie już tylko czekać aż pojawią się (np. w postaci feedu RSS, albo po
prostu strony HTML) pierwsze informacje do niego pasujące. Można też założyć
sobie konto — wtedy nad swoimi subskrypcjami ma się większą kontrolę,
a ich lista nie jest związana z jedną przeglądarką. Można też zainstalować
sobie PubSub sidebar for Firefox (dla IE też jest), który
będzie pokazywał interesujące nas informacje na bierząco. I tu pojawia się
XMPP (rdzeń współczesnego protokołu Jabbera) — ten sidebar to nic
innego, jak prosty klient XMPP z obsługą
pubsub.

Dla siebie stworzyłem zapytania o Pythona, XMPP/Jabbera i o siebie (żebym
od razu wiedział, jak ktoś mnie w sieci obsmarowuje 😉 ). Na temat pythona
dostaję całą masę wiadomości i już trafiłem na jeden ciekawy artykuł:
Python
optimization tips
. O Jabberze jest nieco mniej (między innymi, że jakiś
serwis uznał XMPP za słowo dnia). Pozostałe zapytania nie
pokazały na razie nic. W każdym razie serwis wydaje się interesujący. Nie mogę
się tylko doczekać kiedy mój klient Jabbera będzie umiał pubsub (wiem, wtedy gdy
sobie to napiszę), a PubSub.com udostępni
swoje usługi dla serwerów z zewnątrz (teraz, zdaje się, jest tylko dostęp
z klientów podłączonych bezpośrednio do ich serwera).

Mam go! :-)

Od wielu miesięcy gnębi mnie jeden błąd w CJC: czasem gdy ja coś robię (np.
przełączam bufory) i jednocześnie coś przychodzi z sieci to się wiesza. Typowe
zakleszczenie (deadlock). Wiadomo, że gdzieś źle blokady wątków zastosowałem,
ale to się strasznie źle debuguje (dlatego IMHO wątków należy unikać jak
ognia). Kiedyś próbowałem, ale bardzo się nie postarałem i poległem. Potem po
prostu problem olewałem (pojawiał się tylko raz na jakiś czas, więc można było
z tym żyć). Wczoraj powiesiło się znowu i postanowiłem dzisiaj coś z tym
zrobić.

Najpierw więc dodałem do CJC obsługę pliku konfiguracyjnego dla modułu
logging ze biblioteki pythona (świetna rzecz!). Potem zapuściłem
na źródłach coś takiego:


find . -name "*.py" | xargs perl -pi -e \
's/^(\s+)([\w.]+\.(acquire|release)\(\))[ \t]*$/\1logging.getLogger("lockdebug").debug("\2..."); \2; logging.getLogger("lockdebug").debug("...\2")/'

Po tej operacji odpaliłem CJC, wszedłem na dwa czaty grupowe i zacząłem
przełączać bufory jak szalony. Po jakiejś minucie, czy dwóch zwiesił się
(Murphy poszedł na piwo?). No i chyba mam go! 🙂


2004-10-24 16:49:38,503 window.py: 167 th#16386 DEBUG self.screen.lock.acquire()...
2004-10-24 16:49:38,516 window.py: 167 th#16386 DEBUG ...self.screen.lock.acquire()
2004-10-24 16:49:38,524 text_buffer.py: 42 th#65540 DEBUG self.lock.acquire()...
2004-10-24 16:49:38,525 text_buffer.py: 42 th#65540 DEBUG ...self.lock.acquire()
2004-10-24 16:49:38,526 window.py: 252 th#65540 DEBUG self.screen.lock.acquire()...
2004-10-24 16:49:38,527 text_buffer.py: 208 th#16386 DEBUG self.lock.acquire()...

Teraz pozostaje to poprawić i liczyć na to, że to odosobniony przypadek
:-)

ZPT

System obsługi użytkowników sieci obsługiwanych przez naszą firmę robiłem w Zope.
Prezentację przy użyciu DTML, bo Zope’a uczyłem się z ZopeBook, gdzie o DTML było najwięcej,
a ZPT wyglądał strasznie verbose. Poza tym było tam wyraźnie napisane, że oba rozwiązania
są równorzędne i po prostu DTML bardziej przypadnie do gustu
programiście/hackerowi, a ZPT webmasterowi.

No i system działa, nawet bardzo ładnie działa (wygląda gorzej, ale mnie to
nie obchodzi). Jednak Zope zaczął mnie wkurzać, bo niby proste rzeczy w tym
DTML trzeba było robić na około, a do tego VIM się gubił w składni i podświetlał
mi część kodu jako błędy (w sumie nie dziwię mu się). Poskarżyłem się nawet na
pl.comp.lang.python i tam ktoś mi odpisał, że to DTML jest do d… i należy
używać ZPT. A więc zacząłem czytać o ZPT. I rzeczywiście wygląda dużo lepiej niż DTML,
chyba zaraz spróbuję jakiś prostszy kawałek systemu na to przepisać. Może się przeproszę
z Zopem i kolejny projekt też w nim zrobię? Niestety do metod ZSQL trzeba używać DTML,
a tam to nawet wartości None nie rozumie. Ale z tym się jeszcze da żyć…
Gdyby jeszcze można było używać Subversion do tego to już by było super.

Mix-ins

Gdy w CJC użyłem osobnej klasy (nazwijmy ją A) do
rozszerzenia funkcjonalności innej klasy (B), ale tak, że to
B dziedziczyło po A, to myślałem że stosuję jakiś dziwny,
brudny trik dla własnej wygody. Później czytając dokumentację do
pylinta spotkałem się z określeniem mix-in class, nie
wiedziałem co to jest, ale tak jakoś mi się skojarzyło z tym co zrobiłem w
CJC.

Teraz coś podobnego chcę zrobić w PyXMPP, aby podzielić
jeden wielki moduł pyxmpp.stream na mniejsze kawałki.
Przypomniałem sobie o mix-in class i wrzuciłem to w Google. Okazało się,
że miałem rację. Dowiedziałem, że to znana technika programowania
obiektowego, która wcale nie jest zła. Znalazłem nawet artykuł o tym jak używać mix-ins w
Pythonie
. Rzeczywiście Python bardzo ułatwia stosowanie tej techniki.

No to teraz, gdy się podszkoliłem, mogę z czystym sumieniem wziąć się za
wydzielanie StreamSASLMixIn i StreamTLSMixIn.
:-)

Czy Python nie jest piękny?

Podczas dłubania w jednym skrypcie wyszło mi coś takiego (no tam było trochę czytelniej,
na potrzeby Joggera upiększyłem:

x=[x for x in x if x]

Każdy Pythonowiec od razu zrozumie, że ta instrukcja usuwa puste
(None, "", 0, itp.) elementy z listy
:-). Wiem, w Perlu dałoby się jeszcze mniej czytelnie, pewnie krócej
i na 100 różnych sposobów, ale na pewno nie tak ładnie ;-)

Oczywiście nie polecam takiego programowania — wypadałoby przynajmniej
zmienić jedno x na coś innego.