<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>xlab &#187; python</title>
	<atom:link href="http://xlab.pl/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://xlab.pl</link>
	<description>XSolve laboratory - dzielimy się tym co wiemy...</description>
	<lastBuildDate>Mon, 09 Jan 2012 15:29:06 +0000</lastBuildDate>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Python &#8211; widziany okiem Javianina</title>
		<link>http://xlab.pl/python-widziany-okiem-javianina/</link>
		<comments>http://xlab.pl/python-widziany-okiem-javianina/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 21:22:42 +0000</pubDate>
		<dc:creator>pawel.rychlik</dc:creator>
				<category><![CDATA[Ogólne]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[podstawy]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://xlab.pl/?p=1855</guid>
		<description><![CDATA[Całkiem niedawno wpadł mi w ręce podręcznik do Pythona. Książka wyglądała na interesującą, więc długo nie zwlekając wziąłem się za czytanie, chwilę później już pisałem pierwsze Hello-world&#8216;y w dotąd zupełnie mi obcym języku. Z początku nie bardzo wiedziałem, którą wersje Pythona zainstalować &#8211; strona python.org oferuje multum możliwości, dostępne jest kilkanaście (kilkadziesiąt?) paczek, przygotowanych pod [...]]]></description>
			<content:encoded><![CDATA[<p>Całkiem niedawno wpadł mi w ręce podręcznik do Pythona. Książka wyglądała na interesującą, więc długo nie zwlekając wziąłem się za czytanie, chwilę później już pisałem pierwsze <em>Hello-world</em>&#8216;y w dotąd zupełnie mi obcym języku. Z początku nie bardzo wiedziałem, którą wersje Pythona zainstalować &#8211; strona python.org oferuje multum możliwości, dostępne jest kilkanaście (kilkadziesiąt?) paczek, przygotowanych pod konkretne platformy i maszyny. Pokierowałem się podpowiedziami znalezionymi w internecie: 3.x to najnowsza odmiana tego języka, 2.x jest starszą wersją (ale wciąż rozwijaną do 2013r.). Aplikacje pisane pod 3.x mogą nie być w pełni kompatybilne z Pythonem serii 2.x (i odwrotnie), ponadto większość zewnętrznych bibliotek była pisana pod starszą wersją, dlatego też zdecydowałem się na &#8222;bezpieczne&#8221; 2.6.7.</p>
<p>Nagłówek artykułu sugeruje, że będę starał się dokonać porównania Javy i Pythona. Przecież to dwa kompletnie różne światy. Niemniej jednak postaram się w skrócie nakreślić czym cechuje się Python i opisać co poniektóre ciekawsze rozwiązania, z którymi spotkałem się podczas mojej krótkiej i burzliwej znajomości z tym językiem.</p>
<p><strong>Intro</strong></p>
<p>W odróżnieniu do Javy, Python jest językiem typowanym dynamicznie: zmiennych się nie deklaruje i tym samym nie określa się ich typu. Znaczy to mniej więcej tyle, że do tej samej zmiennej można przypisywać obiekty różnych klas bez potrzeby rzutowania, nie narażając się na odpowiednik javowego <em>ClassCastException</em>. Skoro już mowa o klasach &#8211; Python jest w pełni obiektowy, a więc typy proste (<span style="color: #e34adc">bool</span><span style="color: #808030">,</span> <span style="color: #e34adc">int</span><span style="color: #808030">,</span> <span style="color: #e34adc">float</span><span style="color: #808030">,</span> <span style="color: #e34adc">complex</span>) również są obiektami. Python jest językiem interpretowanym, nie wymagającym kompilacji (ten krok jest opcjonalny &#8211; interpreter może generować skompilowany kod do plików *.pyc). Fakt ten może spodobać się weteranom Javy &#8211; przecież nieraz budowanie złożonych projektów potrafiło zająć ładne parenaście minut. Jednak dynamiczne typowanie w połączeniu z brakiem konieczności kompilacji (który de facto często w pewnym stoponiu weryfikuje poprawność kodu) i nieuwagą programisty może przyczynić się do powstawania błędów. Ale to temat na osobną dyskusję.</p>
<p><strong>Liczby.</strong></p>
<p>Cechą, której nie miałem okazji specjalnie wykorzystać, a która bardzo pozytywnie mnie zaskoczyła, jest wbudowana obsługa liczb zespolonych. Dostępny mamy typ prosty <span style="color: #e34adc">complex</span>.</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> 1j <span style="color: #808030">*</span> 1J
<span style="color: #808030">(</span><span style="color: #808030">-</span><span style="color: #008c00">1</span><span style="color: #808030">+</span>0j<span style="color: #808030">)</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> 1j <span style="color: #808030">*</span> <span style="color: #e34adc">complex</span><span style="color: #808030">(</span><span style="color: #008c00">0</span><span style="color: #808030">,</span><span style="color: #008c00">1</span><span style="color: #808030">)</span>
<span style="color: #808030">(</span><span style="color: #808030">-</span><span style="color: #008c00">1</span><span style="color: #808030">+</span>0j<span style="color: #808030">)</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> a<span style="color: #808030">=</span><span style="color: #008000">1.5</span><span style="color: #808030">+</span><span style="color: #008000">0.</span>5j
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> a<span style="color: #808030">.</span>real
<span style="color: #008000">1.5</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> a<span style="color: #808030">.</span>imag
<span style="color: #008000">0.5</span></pre>
</p>
<p>Kolejną ciekawostką jest fakt, że ograniczeniem długości liczby typu long jest w zasadzie tylko ilość dostępnej pamięci operacyjnej. Dostajemy zatem &#8222;out-of-the-box&#8221; możliwość wyrażania odległości międzygalaktycznych w milimetrach. Tylko co, jeśli będziemy chcieli przekazać obliczony wynik na inną maszynę?</p>
<p><strong>(), [], {}.</strong></p>
<p>Zdarza się, że potrzebujemy, aby metoda zwróciła więcej niż jeden obiekt. Rzecz jasna mowa tu nie o liście/tablicy, ale o obiektach różnych typów. Jednocześnie nie widzimy sensu tworzenia nowej klasy, która i tak byłaby wykorzystana tylko w tym jednym miejscu. Wtedy (na przykładzie Javy) zaczyna się kombinowanie: może przekazywać jeden obiekt przez parametr, w metodzie wypełniać go danymi, a drugą część informacji zwracać przez return statement?; może przejrzeć pakiet *utils w poszukiwaniu generycznej klasy Pair&lt;A,B&gt; lub Trio&lt;A,B,C&gt; i we wspomnianej metodzie zwracać właśnie obiekt takiej klasy? a może spróbować użyć mapę?</p>
<p>Zdaje się, że m.in. wówczas przydałyby się znane z Pythona <em>krotki</em> &#8211; niemodyfikowalne sekwencje referencji dostępnych niezależnie. Dostęp do poszczególnych elementów odbywa się przez podanie indeksu (numeracja od zera).</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #e34adc">tuple</span> <span style="color: #808030">=</span> <span style="color: #008c00">12345</span><span style="color: #808030">,</span> <span style="color: #008c00">54321</span><span style="color: #808030">,</span> <span style="color: #0000e6">'hello!'</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #e34adc">tuple</span>
<span style="color: #808030">(</span><span style="color: #008c00">12345</span><span style="color: #808030">,</span> <span style="color: #008c00">54321</span><span style="color: #808030">,</span> <span style="color: #0000e6">'hello!'</span><span style="color: #808030">)</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #e34adc">tuple</span> <span style="color: #808030">=</span> <span style="color: #808030">(</span><span style="color: #008c00">12345</span><span style="color: #808030">,</span> <span style="color: #008c00">54321</span><span style="color: #808030">,</span> <span style="color: #0000e6">'hello!'</span><span style="color: #808030">)</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #e34adc">tuple</span>
<span style="color: #808030">(</span><span style="color: #008c00">12345</span><span style="color: #808030">,</span> <span style="color: #008c00">54321</span><span style="color: #808030">,</span> <span style="color: #0000e6">'hello!'</span><span style="color: #808030">)</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #e34adc">tuple</span><span style="color: #808030">[</span><span style="color: #008c00">0</span><span style="color: #808030">]</span>
<span style="color: #008c00">12345</span></pre>
</p>
<p>Idąc za ciosem &#8211; kolejnym typem danych jest lista, oznaczana przy pomocy nawiasów kwadratowych. Bardzo podobna do krotki, jednak daje możliwość modyfikacji swoich danych.</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #e34adc">list</span> <span style="color: #808030">=</span> <span style="color: #808030">[</span><span style="color: #0000e6">'spam'</span><span style="color: #808030">,</span> <span style="color: #0000e6">'eggs'</span><span style="color: #808030">,</span> <span style="color: #008c00">100</span><span style="color: #808030">,</span> <span style="color: #008c00">1234</span><span style="color: #808030">]</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #e34adc">list</span>
<span style="color: #808030">[</span><span style="color: #0000e6">'spam'</span><span style="color: #808030">,</span> <span style="color: #0000e6">'eggs'</span><span style="color: #808030">,</span> <span style="color: #008c00">100</span><span style="color: #808030">,</span> <span style="color: #008c00">1234</span><span style="color: #808030">]</span></pre>
</p>
<p>Słowniki, które w Pythonie tworzy się przy użyciu nawiasów klamrowych, prezentują nieco inny sposób grupowania danych. Podczas gdy krotki i listy są numerowane na podstawie indeksów liczbowych, słowniki do indeksacji stosują nazwy &#8211; mogą to być litery, ciągi znaków lub symbole. Słowniki można porównać do java.util.Map, dane wkładamy podając klucz oraz odpowiadającą mu wartość, klucze muszą być unikatowe, jednak pod jednym kluczem wystąpić może wiele wartości.</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> tel <span style="color: #808030">=</span> <span style="color: #800080">{</span><span style="color: #0000e6">'jack'</span><span style="color: #808030">:</span> <span style="color: #008c00">4098</span><span style="color: #808030">,</span> <span style="color: #0000e6">'sape'</span><span style="color: #808030">:</span> <span style="color: #008c00">4139</span><span style="color: #800080">}</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> tel<span style="color: #808030">[</span><span style="color: #0000e6">'guido'</span><span style="color: #808030">]</span> <span style="color: #808030">=</span> <span style="color: #008c00">4127</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> tel
<span style="color: #800080">{</span><span style="color: #0000e6">'sape'</span><span style="color: #808030">:</span> <span style="color: #008c00">4139</span><span style="color: #808030">,</span> <span style="color: #0000e6">'guido'</span><span style="color: #808030">:</span> <span style="color: #008c00">4127</span><span style="color: #808030">,</span> <span style="color: #0000e6">'jack'</span><span style="color: #808030">:</span> <span style="color: #008c00">4098</span><span style="color: #800080">}</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> tel<span style="color: #808030">[</span><span style="color: #0000e6">'jack'</span><span style="color: #808030">]</span>
<span style="color: #008c00">4098</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #800000;font-weight: bold">del</span> tel<span style="color: #808030">[</span><span style="color: #0000e6">'sape'</span><span style="color: #808030">]</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> tel<span style="color: #808030">[</span><span style="color: #0000e6">'irv'</span><span style="color: #808030">]</span> <span style="color: #808030">=</span> <span style="color: #008c00">4127</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> tel
<span style="color: #800080">{</span><span style="color: #0000e6">'guido'</span><span style="color: #808030">:</span> <span style="color: #008c00">4127</span><span style="color: #808030">,</span> <span style="color: #0000e6">'irv'</span><span style="color: #808030">:</span> <span style="color: #008c00">4127</span><span style="color: #808030">,</span> <span style="color: #0000e6">'jack'</span><span style="color: #808030">:</span> <span style="color: #008c00">4098</span><span style="color: #800080">}</span></pre>
</p>
<p>Ciekawym niuansem jest możliwość dostępu do elementów sekwencji podając ujemną wartość indeksu. W Javie chcąc pobrać ostatni element listy, potrzeba mniej więcej takiego kodu: list.get(list.size() &#8211; 1); podczas gdy w Pythonie wystarczy: list[-1]. Przechodząc kolejno elementy listy użylibyśmy indeksów od 0 do len(list)-1. Ten sam efekt można osiągnąć iterując od -len(list) do -1. Taka mała rzecz, a cieszy.</p>
<p>Istnieją również skróty na &#8222;krojenie&#8221; sekwencji. W Javie skorzystalibyśmy z metody List.subList(), która zwraca widok oryginalnej listy. Odpowiadająca temu instrukcja Pythona to zaledwie: list[a:b], gdzie a i b to indeks początkowy i końcowy nowej listy.</p>
<pre style="color: #000000;background: #ffffff">s <span style="color: #808030">=</span> <span style="color: #0000e6">"ABCDEF"</span>
s<span style="color: #808030">[</span><span style="color: #008c00">2</span><span style="color: #808030">:</span><span style="color: #008c00">5</span><span style="color: #808030">]</span>  <span style="color: #808030">-</span><span style="color: #808030">-</span><span style="color: #808030">&gt;</span> <span style="color: #0000e6">"CDE"</span>
s<span style="color: #808030">[</span><span style="color: #008c00">4</span><span style="color: #808030">:</span><span style="color: #808030">]</span>   <span style="color: #808030">-</span><span style="color: #808030">-</span><span style="color: #808030">&gt;</span> <span style="color: #0000e6">"EF"</span>
s<span style="color: #808030">[</span><span style="color: #808030">:</span><span style="color: #008c00">2</span><span style="color: #808030">]</span>   <span style="color: #808030">-</span><span style="color: #808030">-</span><span style="color: #808030">&gt;</span> <span style="color: #0000e6">"AB"</span>
s<span style="color: #808030">[</span><span style="color: #808030">:</span><span style="color: #808030">-</span><span style="color: #008c00">1</span><span style="color: #808030">]</span>  <span style="color: #808030">-</span><span style="color: #808030">-</span><span style="color: #808030">&gt;</span> <span style="color: #0000e6">"ABCDE"</span>
s<span style="color: #808030">[</span><span style="color: #808030">-</span><span style="color: #008c00">1</span><span style="color: #808030">:</span><span style="color: #808030">]</span>  <span style="color: #808030">-</span><span style="color: #808030">-</span><span style="color: #808030">&gt;</span> <span style="color: #0000e6">"F"</span>
s<span style="color: #808030">[</span><span style="color: #808030">:</span><span style="color: #808030">]</span>    <span style="color: #808030">-</span><span style="color: #808030">-</span><span style="color: #808030">&gt;</span> <span style="color: #0000e6">"ABCDEF"</span></pre>
</p>
<p>Kolejny interesujący feature to funkcja range(a, b, c), która zwraca listę liczb od a do b (z opcjonalnym krokiem c), i która często przydaje się przy definiowaniu pętli for..in. Funkcja xrange() spełnia taką samą rolę, jednak poleca się ją stosować przy dużych rozmiarach list: zamiast alokować zbędnie duży fragment pamięci tylko po to, aby trzymać w niej uporządkowane wartości &#8211; xrange() na potrzeby iteracji tworzy tzw. lazy-list, która generuje i udostępnia jedynie elementy potrzebne w danej chwili.</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #696969"># liczenie silni ze 100:</span>
product <span style="color: #808030">=</span> <span style="color: #008c00">1</span><span style="color: #006600">L</span>
<span style="color: #800000;font-weight: bold">for</span> i <span style="color: #800000;font-weight: bold">in</span> <span style="color: #e34adc">xrange</span><span style="color: #808030">(</span><span style="color: #008c00">1</span><span style="color: #808030">,</span> <span style="color: #008c00">100</span><span style="color: #808030">)</span><span style="color: #808030">:</span>
    product <span style="color: #808030">=</span> product <span style="color: #808030">*</span> i</pre>
</p>
<p><strong>Pozostałe małe plusiki</strong></p>
<p>Bardzo istotnym elementem kodu Pythona są białe znaki, a konkretnie wcięcia. To one określają bloki kodu. Z jednej strony jest to plus &#8211; mniej pisania, mniej linii kodu. Jednak błędnie zaaplikowane wcięcia w kodzie (np. wynikające z popularnej techniki copy-paste) mogą spowodować ciężkie do wytropienia błędy.</p>
<p>Świetnym ułatwieniem, które przydałoby się w innych językach, jest możliwość szeregowania (chaining) operatorów porównań:</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> x <span style="color: #808030">=</span> <span style="color: #008c00">5</span>
<span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #008c00">1</span> <span style="color: #808030">&lt;</span> x <span style="color: #808030">&lt;</span> <span style="color: #008c00">10</span>
<span style="color: #e34adc">True</span></pre>
</p>
<p>Porównania wartości String&#8217;ów w Pythonie to kwestia użycia operatorów == lub !=. Daje to sporo poziom przejrzystości kodu, w porównaniu do Javy, gdzie wykorzystalibyśmy String.equals(), compare() lub compareTo().</p>
<p>Podobnie jak w Scali, w Pythonie możliwe jest deklarowanie funkcji wewnątrz funkcji. Zamiast powielać ten sam fragment kodu, lepiej zdefiniować i wywołać nową funkcję. Taka fragmentacja szybko mogłaby doprowadzić do zmniejszenia czytelności interfejsu danej klasy (multum krótkich metod), toteż warto zastanowić się nad umieszczeniem nowej funkcji w ciele funkcji, w której będzie ona używana. Korzystać również możemy z funkcji lambda (któtkich funkcji anonimowych), znanych m.in. z C# i Scali.</p>
<p><strong>&#8222;Talk less, more action&#8221;</strong></p>
<p>Podaje się, że pisząc w Pythonie, można być 5-10 razy bardziej produktywnym niż w Javie. Trudno się temu dziwić, jeśli otwarcie i odczytanie pliku tekstowego w Pythonie sprowadza się do:</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #e34adc">file</span> <span style="color: #808030">=</span> <span style="color: #e34adc">open</span><span style="color: #808030">(</span><span style="color: #0000e6">'plik'</span><span style="color: #808030">)</span>
<span style="color: #e34adc">file</span><span style="color: #808030">.</span>read<span style="color: #808030">(</span><span style="color: #808030">)</span></pre>
</p>
<p>Podczas gdy w Javie należałoby zadeklarować odpowiedni bufor, utworzyć strumień podając ścieżke pliku, prawdopodobnie czytać fragmentami w pętli, całość okraszając tłustą warstwą try {} catch().</p>
<p>Python pozwala na dużą swobodę. Jest językiem skryptowym, ale nie oznacza to, że nie można pisać w nim kodu zorientowanego obiektowo. Oferuje zaawansowaną modularność (wprowadza pojęcie modułu i pakietu), choć właściwie całą, nawet bardziej skomplikowaną aplikację można zawrzeć w jednym pliku *.py.</p>
<p>Python daje duże możliwości. Może być stosowany przy projektach z wielu dziedzin, jako język podstawowy, jak i uzupełniający. Zbudujemy w nim GUI (pyGTK), napiszemy testy jednostkowe (pyUnit), utworzymy zwięzły i treściwy skrypcik użytkowy, dostarczymy plugin do Firefox&#8217;a, tudzież rozszerzenie do Blender&#8217;a, połączymy się z relacyjną bazą danych, obsłużymy dokumenty XML (wbudowane parsery SAX i DOM, narzędzia walidacji, transformacji XML, dodatkowy pakiet PyXML), wreszcie w parudziesięciu liniach zmieścimy prostego klienta email, czy komunikator sieciowy, postawimy aplikację webową (framework Django), w międzyczasie korzystając z bibliotek pisanych w C lub C++.</p>
<p><strong>Ok. Gdzie jest haczyk</strong><strong>?</strong></p>
<p>Python może nie wydawać się stabilną platformą, jeśli w danym momencie korzysta się z elementów, które z czasem się zmieniają. Jeśli chce się budować większą aplikację, warto trzymać się jednej wersji języka. Niestety takie podejście też nie jest najlepsze, bo:</p>
<ul>
<li> Nowsze wersje bibliotek zazwyczaj powstają tylko dla najnowszych wersji Pythona</li>
<li> Pewne nowe elementy Pythona mogą spowodować subtelne zmiany w działaniu aplikacji, które nie dadzą się łatwo wykryć. To z pewnością nie sprzyja biznesowi.</li>
</ul>
<p>Weźmy konkretny przykład. W Pythonie 2.3.4 i wcześniejszym poniższy snippet powoduje wygenerowanie wyniku, którego oczekuje się po programie napisanym w C:</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #800000;font-weight: bold">print</span> <span style="color: #0000e6">"%x"</span> <span style="color: #808030">%</span> <span style="color: #808030">-</span><span style="color: #008c00">2</span>
fffffffe</pre>
</p>
<p>Poczynając od wersji 2.4 widzimy z goła odmienny wynik:</p>
<pre style="color: #000000;background: #ffffff"><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span><span style="color: #808030">&gt;</span> <span style="color: #800000;font-weight: bold">print</span> <span style="color: #0000e6">"%x"</span> <span style="color: #808030">%</span> <span style="color: #808030">-</span><span style="color: #008c00">2</span>
<span style="color: #808030">-</span><span style="color: #008c00">2</span></pre>
</p>
<p>Przedstawiona zmiana może wydawać się błaha, ale tak nie jest. W nowszej wersji Pythona zmianie uległ sposób traktowania liczb całkowitych bez znaku. Ponieważ z liczb całkowitych korzysta się nawet w najmniejszym skrypcie, tego rodzaju zmiana może nieść kolosalne konsekwencje.</p>
<p>Innymi słowy &#8211; Python jest na tyle młodym językiem, że jego twórcy na razie nie przejmują się kwestiami zgodności i stabilności (przynajmniej nie tak bardzo jak w Javie, w której cykle życia oprogramowania obejmują niejednokrotnie 10 lat).</p>
<p>Python to nie tylko maszyna wirtualna, API i składnia &#8211; to także zbiór bibliotek otaczających podstawowe funkcje systemu operacyjnego. Z założenia skrypty pythonowe mają być przenośne pomiędzy systemami operacyjnymi i hardware&#8217;m. Często ochrona przed różnicami pomiędzy systemami jest iluzoryczna, zwłaszcza w kwestii obsługi protokołów sieciowych i wielowątkowości. Np. interfejs gniazd sieciowych, stosowany w wielu programach, zgłasza inne wyjątki pod Windows, a inne pod *nix. Więc albo wyłapuje się wszystkie wyjątki, albo stosuje się osobny kod dla tych przypadków.</p>
<p>Z mojego, subiektywnego punktu widzenia mechanizm dołączania dodatkowych zewnętrznych bibliotek do instancji Pythona jest niekiedy mocno przesadzony. Nie wszystkie biblioteki wymagają instalacji &#8211; niektóre zwyczajnie wrzucamy do katalogu PythonXX\Lib\site-packages i po wykonaniu odpowiedniej instrukcji importu od razu są widoczne z poziomu interpretera. Inne biblioteki dostarczają cały instalator, który teoretycznie powinien wszystkim się zająć.<br />
Ku przestrodze: Instalacja Pythona 2.6.7 pod 64bitowym Windows7 nie powinna stwarzać problemów. Jednak potem doinstalowanie dodatkowych modułów może okazać się już nie takie proste &#8211; biblioteka szuka w rejestrze informacji o ścieżkce instalacji wymaganej wersji Pythona &#8211; i nic nie znajduje. Wtedy niezwykle irytujący staje się fakt, że byle biblioteka (której kod pewnie mieści się na paru ekranach), z wielce wyszukanym instalatorem, jest nie do zainstalowania, choćbyśmy ściągali coraz to inne wersje i samego Pythona i rozszerzeń. Jakby tego było mało &#8211; deinstalacja pod Win7 trwa ~8minut, i zostawia po sobie multum śmieci, m.in. w katalogach systemowych.</p>
<p>Dużym minusem jest brak możliwości debuggowania wątków (oczywiście można próbować to &#8222;obejść&#8221; przy pomocy logger&#8217;a, lub pisząc dokładne testy jednostkowe).</p>
<p><strong>Outro</strong></p>
<p>Python jest narzędziem zorientowanym na maksymalną zwięzłość, prostotę i wysoki stopień abstrakcji. Dzięki temu pozwala na szybkie i efektywne tworzenie aplikacji. Pozwala skupić się na samej funkcjonalności programu, odkładając kwestie niskopoziomowe na dalsze tło. Byłby świetnym wyborem, kiedy przyjdzie potrzeba napisania na szybko prostego skryptu, czy niewielkiej aplikacji w ramach uczelnianego projektu. Zdaje się, że nie jest to jeszcze język na tyle dojrzały, ustabilizowany i konsekwentny, aby na jego podstawie pisać rozbudowane aplikacje biznesowe o długim cyklu życia. Chyba, że jako wyjątkowo wysoko-poziomowy język uzupełniający, stanowiący niewielką część całości aplikacji.</p>
<p><strong>Polecam</strong></p>
<p><a title="http://stackoverflow.com/questions/101268/hidden-features-of-python" href="http://stackoverflow.com/questions/101268/hidden-features-of-python" target="_blank">http://stackoverflow.com/questions/101268/hidden-features-of-python</a></p>
]]></content:encoded>
			<wfw:commentRss>http://xlab.pl/python-widziany-okiem-javianina/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Why I hate Django</title>
		<link>http://xlab.pl/why-i-hata-django/</link>
		<comments>http://xlab.pl/why-i-hata-django/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 16:52:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Ogólne]]></category>
		<category><![CDATA[cal henderson]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.xlab.pl/?p=10</guid>
		<description><![CDATA[DjangoCon i Cal Henderson z Flickr, zobaczcie bo warto:]]></description>
			<content:encoded><![CDATA[<p>DjangoCon i Cal Henderson z Flickr, zobaczcie bo warto:<br />
<span id="more-10"></span><br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="src" value="http://www.youtube.com/v/i6Fr65PFqfk&amp;hl=en&amp;fs=1" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/i6Fr65PFqfk&amp;hl=en&amp;fs=1" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://xlab.pl/why-i-hata-django/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

