<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Django - zab&#243;jcza aplikacja. </title>
    <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>Django - zab&#243;jcza aplikacja. </title>
      <description>&lt;p&gt;Musz&#281; przyzna&#263;, &#380;e podoba mi si&#281; zar&#243;wno spos&#243;b, jak i kierunek, w kt&#243;rym rozwijany jest pythonowy framework &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt;. Nie jest to kolejny domowy projekt tworzony w ramach hobby (jak to by&#322;o z &lt;a href="http://cherrypy.org"&gt;CherryPy&lt;/a&gt;). Django powstawa&#322;o od razu z za&#322;o&#380;eniem pracy w ci&#281;&#380;kim &#347;rodowisku produkcyjnym. Ostatnio napisa&#322;em sobie (w ramach zabawy) pewn&#261; aplikacj&#281; w Django i musz&#281; przyzna&#263;, &#380;e praca z Django jest faktycznie komfortowa. Wy&#380;sza ni&#380; w &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt;, i wy&#380;sza nawet ni&#380; w &lt;a href="http://rubyonrails.com"&gt;Railsach&lt;/a&gt;. Aby tekst nie by&#322; za d&#322;ugi, podziel&#281; go na kilka mniejszych tekst&#243;w. Przedstawi&#281; swoje spostrze&#380;enia co do Pythona jako j&#281;zyka na tle Rubiego. Potem opisz&#281; powody dla kt&#243;rych Django ma wielkie szanse sta&#263; si&#281; &lt;em&gt;killer application&lt;/em&gt; dla Pythona. Oraz w kolejnych cz&#281;&#347;ciach opisz&#281; krok po kroku tworzenie konkretnej aplikacji w Django. Dzi&#347; b&#281;dzie kr&#243;tko o Pythonie.&lt;/p&gt;


	&lt;h2&gt;Przewaga Pythona&lt;/h2&gt;


	&lt;p&gt;Gdy zaczynam m&#243;wi&#263; o &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt;, to od razu nasuwa mi si&#281; por&#243;wnanie do &lt;a href="http://rubyonrails.com"&gt;Ruby on Rails&lt;/a&gt;. Django jest oparty na j&#281;zyku &lt;a href="http://python.org"&gt;Python&lt;/a&gt;, a Rails na j&#281;zyku &lt;a href="http://ruby-lang.org"&gt;Ruby&lt;/a&gt;. 
Co by nie m&#243;wi&#263; o zaletach Rubiego, to Python posiada kilka cech, kt&#243;re moim zdaniem, stawiaj&#261; go wy&#380;ej&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;


	&lt;h3&gt;Python jest szybszy.&lt;/h3&gt;


	&lt;p&gt;To po prostu jest fakt i to wida&#263; go&#322;ym okiem. Python automatycznie kompiluje ka&#380;dy modu&#322; do &lt;strong&gt;bytecodu&lt;/strong&gt;. To jest operacja ca&#322;kowicie przezroczysta dla programisty. Bytecode przy du&#380;ym projekcie sk&#322;adaj&#261;cym si&#281; w setek plik&#243;w przy&#347;piesza znacznie czas &#322;adowania kodu i mo&#380;e od biedy s&#322;u&#380;y&#263; r&#243;wnie&#380; jako proste zabezpieczenie &#378;r&#243;de&#322;. Python jest szybszy nie tylko od Rubiego, ale tak&#380;e od &lt;span class="caps"&gt;PHP&lt;/span&gt;. Robi&#322;em kiedy&#347; por&#243;wnanie prostej aplikacji w mod_php5 vs &lt;a href="http://myghty.org"&gt;Myghty&lt;/a&gt;. Zdziwi&#322;o mnie wtedy to, &#380;e Python by&#322; tu szybszy, bo &lt;span class="caps"&gt;PHP&lt;/span&gt; jest zoptymalizowany do szybkiego wykonywania prostych skrypt&#243;w. Oczywi&#347;cie, im wi&#281;kszy kod, tym ro&#347;nie przewaga Pythona z powodu u&#380;ycia bytecodu&lt;sup&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;h3&gt;Python jest &#322;atwiejszy do nauki.&lt;/h3&gt;


	&lt;p&gt;Pythona &#322;atwiej mo&#380;na si&#281; nauczy&#263; i pos&#322;ugiwa&#263; ni&#380; Rubiego czy nawet &lt;span class="caps"&gt;PHP&lt;/span&gt; (sic!). To jest bardzo wa&#380;ny punkt, bo dotyczy kluczowej kwestii jak&#261; jest &lt;strong&gt;produktywno&#347;&#263; programisty&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;Filozofi&#261; Pythona jest aby by&#322;o jak najmniej mo&#380;liwych dr&#243;g do rozwi&#261;zania tego samego problemu. Z tego wynika, &#380;e Python stara si&#281; implementowa&#263; &lt;strong&gt;jak najmniejsz&#261; ilo&#347;&#263;&lt;/strong&gt; funkcji i metod. Znacznie to u&#322;atwia poruszanie si&#281; po tych metodach. W wypadku Rubiego, nie do&#347;&#263;, &#380;e mamy znacznie wi&#281;cej metod na obiekt, to na dodatek, lista metod jest dodatkowo &lt;strong&gt;za&#347;miecona&lt;/strong&gt; aliasami. W Ruby mamy po kilka metod, kt&#243;re wykonuj&#261; &lt;em&gt;to samo&lt;/em&gt;. Po kilka konstrukcji j&#281;zykowych, kt&#243;re robi&#261; &lt;em&gt;to samo&lt;/em&gt;. Wida&#263; tu korzenie fascynacji &lt;a href="http://perl.org"&gt;Perlem&lt;/a&gt;. Ale dla programist&#243;w to jest uci&#261;&#380;liwo&#347;&#263;.&lt;/p&gt;


	&lt;h3&gt;Python jest bardziej produktywny.&lt;/h3&gt;


	&lt;p&gt;Dodatkowym czynnikiem u&#322;atwiaj&#261;cym szybk&#261; prace, jest integracja prostego mechanizmu dokumentacji kodu na poziomie sk&#322;adni Pythona. Mowa o &lt;a href="http://blog.zabiello.com/articles/2006/03/06/dokumentacja-dla-leniwych-pot%C4%99ga-pythona"&gt;docstringach&lt;/a&gt;. W praktyce znaczy to, &#380;e prawie wszystkie edytory &lt;span class="caps"&gt;IDE&lt;/span&gt; (kt&#243;rych jest sporo, s&#261; darmowe i s&#261; bardzo dobre jak na t&#281; klas&#281; j&#281;zyk&#243;w) nie tylko rozwijaj&#261; mniej metod, ale tak&#380;e wy&#347;wietlaj&#261; ich zintegrowan&#261; dokumentacj&#281;. Efektem jest znacznie mniej czasu traconego na zagl&#261;danie do dokumentacji czy ksi&#261;&#380;ek. To du&#380;a, odczuwalna r&#243;&#380;nica. Mniej rzeczy do zapami&#281;tania, podpowiedzi do sk&#322;adni na ka&#380;dym kroku, to musi si&#281; odbijac na produktywno&#347;ci tworzenia kodu&lt;sup&gt;&lt;a href="#fn3"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;h3&gt;Python ma pe&#322;n&#261; obs&#322;ug&#281; Unicode.&lt;/h3&gt;


	&lt;p&gt;Pe&#322;nej obs&#322;ugi Unicode nie ma ani &lt;span class="caps"&gt;PHP&lt;/span&gt; ani Ruby. Obs&#322;uguj&#261; co najwy&#380;ej &lt;span class="caps"&gt;UTF&lt;/span&gt;-8 i to w ograniczonym zakresie. Np. pr&#243;by konwersji znak&#243;w ze standardu cp1250 (typowa sytuacja dla polskiego serwera &lt;span class="caps"&gt;MSSQL&lt;/span&gt;) do latin2 (typowe dla serwera MySQL w internecie) skazane s&#261; na korzystanie z biblioteki iconv, co jest dosy&#263; chorym rozwi&#261;zaniem. Chorym, bo iconv nie umie dawa&#263; sobie rady z wieloma znakami, kt&#243;re nie maj&#261; odpowiednika w standarcie latin2. Chodzi nie o polskie ogonki, ale o r&#243;&#380;nego rodzaju d&#322;ugie my&#347;lniki, polskie, dolne cudzys&#322;owy itp.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; &#8222;To jest jaki&#347; tekst &#8212; spr&#243;buj to skonwertowa&#263; z cp1250 do latin2.&#8221;  &lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt; \x84To jest jaki\x9c tekst \x97 spr\xf3buj to skonwertowa\xe6 z cp1250 do latin2.\x94  &lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; &#8222;To jest jaki&#347; tekst &#8212; spr&#243;buj to skonwertowa&#263; z cp1250 do latin2.&#8221;  &lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt; \x84To jest jaki\x9c tekst \x97 spr\xf3buj to skonwertowa\xe6 z cp1250 do latin2.\x94  &lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;u&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;unicode&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;cp1250&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;u&lt;/span&gt;
&lt;span class="ident"&gt;u&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt; \u201eTo jest jaki\u015b tekst \u2014 spr\xf3buj to skonwertowa\u0107 z cp1250 do latin2.\u201d  &lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;u&lt;/span&gt;
 &#8222;&lt;span class="constant"&gt;To&lt;/span&gt; &lt;span class="ident"&gt;jest&lt;/span&gt; &lt;span class="ident"&gt;jaki&#347;&lt;/span&gt; &lt;span class="ident"&gt;tekst&lt;/span&gt; &#8212; &lt;span class="ident"&gt;spr&#243;buj&lt;/span&gt; &lt;span class="ident"&gt;to&lt;/span&gt; &lt;span class="ident"&gt;skonwertowa&#263;&lt;/span&gt; &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="ident"&gt;cp1250&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="ident"&gt;latin2&lt;/span&gt;&lt;span class="punct"&gt;.&#8221;&lt;/span&gt;  
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;latin2&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;u&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;encode&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;iso-8859-2&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;xmlcharrefreplace&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;latin2&lt;/span&gt;
&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt; &amp;amp;#8222;To jest jaki\xb6 tekst &amp;amp;#8212; spr\xf3buj to skonwertowa\xe6 z cp1250 do latin2.&amp;amp;#8221;  &lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Nie chodzi tylko o konwersje znak&#243;w. Dzi&#281;ki Unicode, w Pythonie mo&#380;esz dokonywa&#263; rzeczy bardzo trudnych do uzyskania w &lt;span class="caps"&gt;PHP&lt;/span&gt; czy Ruby. Operacje na tek&#347;cie potrafi&#261; poprawnie traktowa&#263; polskie znaczki. Np. napisanie funkcji implementuj&#261;cej pod&#347;wietlanie wyszukiwanych s&#322;&#243;w bez wzgl&#281;dy na to czy uzyto du&#380;ych, czy ma&#322;ych polskich znak&#243;w. Dla bazy &lt;span class="caps"&gt;SQL&lt;/span&gt; to &#380;aden problem&lt;sup&gt;&lt;a href="#fn4"&gt;4&lt;/a&gt;&lt;/sup&gt;  ale dla kodu?&lt;/p&gt;


	&lt;p&gt;Chcieliby&#347;my aby wyra&#380;eniem regularnym podmieni&#263; jakie&#347; s&#322;owa zawieraj&#261;ce polskie znaczkiNp. wyra&#380;enia regularne umiej&#261; reagowa&#263; poprawnie na polskie ogonki!&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#-*- coding: utf-8 -*-&lt;/span&gt;
&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;highlight&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tekst&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;slowo&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;encoding&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;isinstance&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tekst&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;unicode&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
        &lt;span class="ident"&gt;tekst&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;unicode&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tekst&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;encoding&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;isinstance&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;slowo&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;unicode&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
        &lt;span class="ident"&gt;slowo&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;unicode&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;slowo&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;encoding&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;replace&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;compile&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;(&lt;/span&gt;&lt;span class="punct"&gt;'+&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;escape&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;slowo&lt;/span&gt;&lt;span class="punct"&gt;)+'&lt;/span&gt;&lt;span class="string"&gt;)&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;I&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;U&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;sub&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;replace&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;b&amp;gt;\1&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;tekst&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;highlight&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;pod&#347;wietl g&#281;&#347; G&#280;&#346;, G&#281;&#346;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;g&#281;&#347;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;cp1250&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; 
&lt;span class="comment"&gt;# =&amp;gt; pod&#347;wietl &amp;lt;b&amp;gt;g&#281;&#347;&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;G&#280;&#346;&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;G&#281;&#346;&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Jeszcze jedno. Microsoft &amp;#8220;uszcz&#281;&#347;liwi&#322;&amp;#8221; nasz kilkoma standardami kodowania polskich znak&#243;w. Inny jest dla windows (cp1250) a inny dla konsoli okienka &lt;span class="caps"&gt;DOS&lt;/span&gt; (cp852). Python pozwala ca&#322;kowicie zapomnie&#263; o stringach i kodowaniach. Po prostu nale&#380;y pracowa&#263; na &lt;strong&gt;obiektach Unicode&lt;/strong&gt;. Powtarzam: obiektach Unicode a nie stringach &lt;span class="caps"&gt;UTF&lt;/span&gt;-8, bo to nie to samo. Instrukcja print wy&#347;wietli poprawnie polskie znaki, je&#347;li operujemy na obiekcie unicode.&lt;/p&gt;


	&lt;h3&gt;Python ma stabilniejsze i dojrzalsze biblioteki.&lt;/h3&gt;


	&lt;p&gt;Przekona&#322;em si&#281; &lt;a href="http://blog.zabiello.com/articles/2006/04/19/modularyzacja-ror-komponenty"&gt;na swojej sk&#243;rze&lt;/a&gt;, co znaczy przekonwertowa&#263; setki plik&#243;w graficznych za pomoc&#261; biblioteki &lt;a href="http://rmagick.rubyforge.org/"&gt;RMagick&lt;/a&gt; (Ruby), a za pomoc&#261; &lt;a href="http://www.pythonware.com/products/pil/"&gt;&lt;span class="caps"&gt;PIL&lt;/span&gt;&lt;/a&gt; (Python). Kod w Ruby po&#380;ar&#322; mi ca&#322;a pami&#281;&#263; i odm&#243;wi&#322; pracy&amp;#8230;&lt;/p&gt;


	&lt;p&gt;&lt;del&gt;-&lt;/del&gt;&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Osobn&#261; kategori&#261; jest j&#281;zyk &lt;span class="caps"&gt;PHP&lt;/span&gt;. W&#322;a&#347;ciwie szkoda gada&#263;. Ci, co zakosztowali pracy z Pythonem i Ruby, trac&#261; szybko zapa&#322; do mozolnego d&#322;ubania w chaotycznym, niesp&#243;jnym, &#378;le zaprojektowanym j&#281;zyku &lt;a href="http://php.net"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/a&gt;. Na ten temat to chyba trzeba napisa&#263; oddzielny tekst. Jak znajd&#281; czas, to sobie &amp;#8220;pou&#380;ywam&amp;#8221; na &lt;span class="caps"&gt;PHP&lt;/span&gt;. :)&lt;/p&gt;


	&lt;p id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; Aby &lt;span class="caps"&gt;PHP&lt;/span&gt; a&#380; tak nie odstawa&#322;, trzeba u&#380;y&#263; akcelerator. Niekt&#243;re z&#322;o&#380;one projekty &lt;span class="caps"&gt;PHP&lt;/span&gt;, jak ezPublish, bez akceleratora s&#261; koszmarnie wolne.&lt;/p&gt;


	&lt;p id="fn3"&gt;&lt;sup&gt;3&lt;/sup&gt; Najlepszym przyk&#322;adem r&#243;&#380;nicy mi&#281;dzy Pythonem a np. .NET jest ostatnio zaimplementowany przez mnie system synchronizacji danych mi&#281;dzy serwerami. Projekt tworzony przez 6 miesi&#281;cy w VB.NET (.NET) zosta&#322; napisany od zera w 5 roboczych dni (z czego dzia&#322;aj&#261;cy prototyp by&#322; dost&#281;pny po paru godzinach). &#379;eby by&#322;o ciekawiej, nowy kod Pythona w tym wypadku dzia&#322;a i szybciej i stabilniej.&lt;/p&gt;


	&lt;p id="fn4"&gt;&lt;sup&gt;4&lt;/sup&gt; Np. dla MySQL (od wersji 4.1 wzwy&#380;) trzeba tylko ustawi&#263; aby baza pracowa&#322;a natywnie w utf8 (domy&#347;lnie jest latin1) i tabele oraz ich pola tekstowe mia&#322;y ustawiony parametr collations na                       &lt;strong&gt;utf8_polish_ci&lt;/strong&gt;.&lt;/p&gt;


	&lt;p style="text-align:center;"&gt;(Zobacz: &lt;a href="http://blog.zabiello.com/articles/2006/05/27/django-zab%C3%B3jcza-aplikacja-cz%C4%99%C5%9B%C4%87-ii"&gt;cz&#281;&#347;&#263; II&lt;/a&gt;)&lt;/p&gt;</description>
      <pubDate>Sat, 27 May 2006 10:17:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:0e2566cb-b75b-4c9e-b8d9-3611ec49ecb2</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji</link>
      <category>Python</category>
      <category>Django</category>
      <category>django</category>
    </item>
    <item>
      <title>"Django - zab&#243;jcza aplikacja. " by daniel- chazol@poczta.fm</title>
      <description>&lt;p&gt;czesc mam pytanko szukam wszedzie po internecie czegos na temat UNICODE czy posiadasz wiedze na ten temat. prosze o kontakt gg 4014674 email &lt;a href="mailto:chazol@poczta.fm" rel="nofollow"&gt;chazol@poczta.fm&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 14 Sep 2006 12:50:13 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:5007eba9-6513-4f84-9dad-a9e9856d3b03</guid>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji#comment-225</link>
    </item>
    <item>
      <title>"Django - zab&#243;jcza aplikacja. " by skk</title>
      <description>&lt;p&gt;jesli moge sie dolaczyc: nie jestem programista, chociaz przecioralem sie w swoim zyciu przez rozne kursy C, C++, VB, HTML etc etc, bo wydawalo mi sie, ze ktos, kto uzywa komputera profesjonalnie, powinien wiedziec &amp;#8220;czym to sie je&amp;#8221;. 
Co jakis czas potrzebuje napisac sobie proste narzedzie i z tego punktu widzienia Python jest dla mnie zbawca. Nigdy nie naczy&#322;bym sie programowac (nawet na tak podstaworym poziomie) gdyby nie Python. Jego zadziwiajaca prostota moze umykac profesjonalnym programistom. Dla takich ludzi jak ja, to zupelnie podstawowa sprawa: to, ze kod pythona wyglada jak pseudokod. Otoz z Rubym juz tak nie jest. Wiem, ze to dobrze zaprojektowany program i elegancki, ale co mnie zrazilo do niego, to stosowanie roznych &amp;#8220;kruczkow&amp;#8221; dla szybszego zapisywania kodu. Nie przypomne sobie teraz przykladu, ale juz na drugiej lub trzeciej lekcji w Rubym pojawiaja sie &amp;#8220;sposobiki&amp;#8221; jak cos ujac w sposob mniej czytelny, ale za to szybszy. Natymiast zaczalem sie gubic. No i do tego moduly w Pythonie&amp;#8230; :) rzeczy niemozliwe dla nie bez Pythona, stoja otworem. Z tego co wiem, mimo swej porazajacej prostoty, to bardzo potezne narzedzie, w przeciwienstwie do VBasica.&lt;/p&gt;</description>
      <pubDate>Fri, 16 Jun 2006 08:43:41 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:03377c33-8d69-4c59-a63d-987542b5ab05</guid>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji#comment-148</link>
    </item>
    <item>
      <title>"Django - zab&#243;jcza aplikacja. " by Adamh</title>
      <description>&lt;p&gt;W tych minusach zgadzam sie (pojawily sie one juz w tekscie). Przestrzen nazw &amp;#8211; wspaniala rzecz, tak jak docstringi i proba minimalizowania aliasow metod.&lt;/p&gt;


	&lt;p&gt;PS z tego co wiem to NASA i ponoc Google uzywaja rowniez Ruby&amp;#8217;ego :) Oczywiscie nie na taka skale jak Pythona (szczegolnie Google jak wiadomo).&lt;/p&gt;


	&lt;p&gt;Python stal sie bardzo popularny sam w sobie jako jezyk. Ruby stal sie bardzo popularny jako fundament Railsow &amp;#8211; choc to rowniez sie zmienia.
Ciekawy jestem jaki bedzie Ruby 2.0&lt;/p&gt;</description>
      <pubDate>Sun, 28 May 2006 10:26:21 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:a4963261-0e62-4cbb-9256-03eff8c85a47</guid>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji#comment-122</link>
    </item>
    <item>
      <title>"Django - zab&#243;jcza aplikacja. " by Jaros&#322;aw Zabie&#322;&#322;o</title>
      <description>&lt;p&gt;Adamh: to prawda, &#380;e kod Rubiego jest bardzo elegancki. Ale mam wra&#380;enie, &#380;e jak si&#281; w tym cz&#322;owiek zag&#322;&#281;bia, to znacznie &#322;atwiej si&#281; pogubi&#263;. Nie wiadomo sk&#261;d pojawiaj&#261; si&#281; jakie&#347; metody i funkcje. Masz kup&#281; includowanych plik&#243;w (require) kt&#243;re &#322;aduj&#261; kolejne i gdzie&#347; w tym &#322;a&#324;cuchu co&#347; jest odpalone, co&#347; innego dodane do przestrzeni nazw.&lt;/p&gt;


	&lt;p&gt;B&#281;d&#281; si&#281; upiera&#322;, ale wol&#281; minimalistyczne podej&#347;cie Pythona. Wol&#281; jak mi edytor rozwinie 10 metod do obiektu a nie 1000 z czego po&#322;owa to aliasy (oczywi&#347;cie przesadzam ;). Co do konstrukcji j&#281;zyka, to bym mo&#380;e nie by&#322; ju&#380; tak zasadniczy, bo to mi nie przeszkadza (sk&#322;adnia Rubiego mi si&#281; podoba). Przeszkadza mi tylko nadmiar metod i ich duplikacj oraz spos&#243;b dodawania czego&#347; do przestrzeni nazw.&lt;/p&gt;


	&lt;p&gt;Pawe&#322;: Ja tylko opisuj&#281; swoje wra&#380;enia. Poza RMagickiem mia&#322;em tak&#380;e nieprzyjemny epizod z modu&#322;em mysql do windozy. Wywala&#322; mi core dump. Na szcz&#281;&#347;cie pom&#243;g&#322; p&#243;&#378;niejszy upgrade. Python jest szerzej stosowany i to na spor&#261; skal&#281; (Google, NASA itp.) &amp;#8211; wydaje mi si&#281; to raczej oczywiste, &#380;e jego biblioteki s&#261; lepiej dopracowane. O Ruby tak naprawd&#281; zacz&#281;to szerzej m&#243;wi&#263; dopiero od czasu powstania Rails&#243;w.&lt;/p&gt;</description>
      <pubDate>Sun, 28 May 2006 09:51:28 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:06f65162-864c-456e-a2af-5ebf53475e96</guid>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji#comment-121</link>
    </item>
    <item>
      <title>"Django - zab&#243;jcza aplikacja. " by Pawel Rutkowski</title>
      <description>&lt;p&gt;Apropo stabilniejszych bibliotek dla Pythona. Mozesz przytoczyc jakies dodatkowe przyklady ? Bo takie stwierdzenie na podstawie jednej biblioteki jest malo obiektywne.&lt;/p&gt;


	&lt;p&gt;Juz wczesniej pisalem ze robilem cuda na RMagicku+GraphicsMagick i na takie problemy nie trafilem.&lt;/p&gt;</description>
      <pubDate>Sun, 28 May 2006 06:15:19 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:1bdd02be-cba3-4552-af7b-f69786fbb457</guid>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji#comment-115</link>
    </item>
    <item>
      <title>"Django - zab&#243;jcza aplikacja. " by Adamh</title>
      <description>&lt;p&gt;Co do przewagi Pythona nad Rubym zgodze sie z tymi argumentami ale warto nadmienic dlaczego tak wiele osob stawia Ruby na piedestale (np ja). Moim zdaniem kod pisany w Rubym jest tak bardzo przejrzysty, ze praktycznie nie wymaga komentowania. Tworzenie tego kodu jest wrecz zabawa (trzeba to poczuc programujac wczesniej w PHP lub Javie). 
Moim zdaniem w Rubym programuje sie szybciej (fakt, ze lepiej znam Ruby niz Pythona ale nadrabiam:))
Wiele osob chwali Pythona za jedno dobre rozwiazanie &amp;#8211; dla mnie piekny jest wybor rozwiazania i drogi wg moich preferencji (fakt, ze ktos musi sie wtedy na inne do swego podejscie przestawic).&lt;/p&gt;


	&lt;p&gt;Django jest inne niz Rails tak jak Python inny niz Ruby i na pewno znajda sie ludzie preferujacy jedna lub druga filozofie. Piekne jest to, ze powstaja naprawde dobre alternatywy.&lt;/p&gt;</description>
      <pubDate>Sun, 28 May 2006 05:44:32 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:cbc1cba5-9990-4130-aa21-a3c278acc7cf</guid>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji#comment-114</link>
    </item>
  </channel>
</rss>
