[Python] mod_python ed il giusto handler

Valentino Volonghi aka Dialtone dialtone a divmod.com
Ven 18 Ago 2006 21:28:49 CEST


On Fri, 18 Aug 2006 20:33:37 +0200, Andrea Giammarchi <andrea a 3site.it> wrote:
>Valentino Volonghi aka Dialtone ha scritto:
>>Trovo questo modo di introdurre una roba di php in python piuttosto 
>>discutibile,
>io non introduco niente ... la libreria lavora in background, l'introduzione 
>del formato serialize di PHP è lo stesso identico concetto di JSON, esistono 
>versioni di serialize / unserialize per quasi lo stesso numero di linguaggi 
>eh ... non è una novità e permetterebbe a tale libreria di lavorare su più 
>linguggi server invece che su uno solo, tutto qua


>>ad ogni modo: come funziona questo formato?
>int => i:N;
>float => d:F;
>bool => b:N; (dove N è 0 o 1 a seconda che sia True o False)
>string => s:N:"stringa"; (dove N è la lunghezza della stringa solo se questa 
>non è stata encodata in utf8 e non contiene caratteri multi-bytes)

E questo come e` possibile? Puoi inviare solo ascii? 

>e hai detto niente ... visto che lo stato ti permette di ricostruire, sul 
>client se presente, o sul server, se presente, un'istanza aggiornata 
>dell'oggetto.

Si ho detto niente. Un oggetto e` stato e metodi assieme. Se hai solo stato
usare gli oggetti non e` un bene ma un male perche` introduci complessita`
senza motivo. Inoltre se il tuo sogno e` tenere aggiornate le istanzi degli
oggetti tra server e client vivrai una vita grama e ricca di spiacevoli sorprese.

>perchè i dizionari non sono istanze di oggetti ma appunto dizionari ?

Embe`? L'object system di javascript e` comunque diverso da quello di python e
comunque devi riscrivere la classe sia in python che in javascript. Basta
passare gli argomenti per istanziarla lato javascript, tanto _NON_ devono fare
le stesse cose perche` _NON_ sono le stesse ed e` bene che _NON_ vengano neanche
lontanamente rese simili perche` confonderebbero lo sviluppo mischiando logica.

>perchè non puoi usare o inviare classi client / server e gestirne lo stato ?

Perche` la tua frase sopra non ha senso. L'"e" e` assolutamente inutile perche`
per quello che fai e` la stessa cosa non una cosa in piu`.

>significa che ogni client si gestisce la sua istanza delel sue classi, 
>significa un approccio completamente OO anche sul client, usando anche 
>classi e non solo {}

A parte che l'approcio completamente OO non significa nulla. Ma non vedo come
questo modo di serializzare de-serializzare oggetti possa far cambiare l'approcio.

Sono due cose _COMPLETAMENTE_ diverse. Uno e` la trasmissione di stato da un
server al client e l'altro e` un modello di sviluppo dei client. Sono due livelli
completamente separati.

>prima dici del po po di roba, poi mi parli dell'inutilità di inviare stati 
>di oggetti, quidi implementeresti un metodo dedicato che a seconda della 
>classe assegna eventualmente quello o quell'altro parametro all'istanza 
>dell'oggetto ??? ... io invio istanze, non devo fare altro, inutile eh ? per 
>me non lo è mai stato, sarò io che ho i paraocchi bucati ?

Si. Faccio un esempio del codice javascript lato client su cui lavoro
abitualmente visto che probabilmente quello di cui parlo e` piu` complesso di
quello che sembra:

Wirc = {};

Wirc.Controller = Nevow.Athena.Widget.subclass('Wirc.Controller');

Wirc.Controller.methods(
    function connect(self, nickname) {
        self.nickname = nickname;
        self.callRemote('connect', nickname);
    },
    function disconnect(self) {
        self.callRemote('disconnect');
    },
    function send(self, line) {
        var action_index = line.indexOf("/action");
        var me_index = line.indexOf("/me");
        var me_pos = action_index > -1 ? action_index : me_index;
        
        if (me_pos > -1) {
            var arr = line.split(" ");
            var lst = MochiKit.Base.filter(function(elem) {
                if ((elem == "/action") || (elem == "/me")) {
                    return false;
                } else {
                    return true;
                }
            }, arr);
            line = lst.join(" ");
            self.callRemote("action", line);
            append_message("*", self.nickname + " " + line);
        } else {
            self.callRemote("send", line);
            append_message(self.nickname, line);
        }
        var node = MochiKit.DOM.getElement('inputForm');
        node.inputLine.value = "";
    },
    function receive(self, user, msg) {
        append_message(user, msg);
    },
    function updateTopic(self, message) {
        MochiKit.DOM.replaceChildNodes('topic', message);
    },
    function updateUsers(self, users) {
        var userlist = MochiKit.DOM.getElement('usersList');
        try {
            MochiKit.DOM.removeElement('to-remove');
        } catch (e) { /*I don't care */ }
        
        for (var i = 0; i < users.length; i++) {
            var li = MochiKit.DOM.LI({}, users[i]);
            userlist.appendChild(li);
        }
    },
    function info_joined(self, user) {
        append_message(user, user+' joined');
        self.updateUsers([user]);
    },
    function info_left(self, user ) {
        append_message(user, user+' left');
    },
    function info_quit(self, user, msg) {
        append_message(user, 'quit: '+msg);
        var userlist = MochiKit.DOM.getElement('usersList');
        MochiKit.Iter.forEach(userlist.children, function (item) {
            if (item.innerHTML == user) {
                MochiKit.DOM.removeElement(item);
            }
        });
    }
);

Io uso JSON e mi sembra di usare un approcio a oggetti piuttosto spinto lato
client. Giuro inoltre che potrei mostrarti una tonnellata di javascript molto
piu` complesso di questo che utilizza ancora JSON.

>ma non puoi usare un metodo, come se fose istanza di classe ...

Il metodo lo devi scrivere comunque in javascript quindi questo non c'entra
niente.

>e chi lavora il doppio ? lavoro per la lib, finita quella basta ... la lib è 
>finita, mancano dettagli ...

Lavori il doppio perche` il tuo modello e` enormemente piu` complesso da gestire.

>si, pazienza, tanto dato i tuoi discorsi lavori solo con dizionari, chissà 
>quali "stratagemmi" per ricreare i metodi, stratagemmi inutili quando puoi 
>inviare già un oggetto con quel metodo, poi l'invio di più oggetti non ne 
>parliamo

Vedi sopra. Ma te lo ripeto perche` ti e` difficile capirlo evidentemente:
non puoi inviare metodi con la serializzazione ma solo lo stato quindi i metodi
devi comunque scriverli per cui non mischiare troppi argomenti.

>Intendo dire (in modo sicuramente ridicolo e mi ero scordato che qui non 
>passava niente nemmeno se prontamente commentato) che una classe client può 
>avere (come no) un riscontro con la classe server e vice-versa ma che le due 
>classi si comportano in modo differente sul client e sul server.

Come? E questo cosa ha a che fare col polimorfismo?

>Non è mica detto che la classe client debba avere il metodo fileWrite 
>presente invece in quella server, è però vero che lo stato dell'istanza può 
>viaggiare e permetterti di usare obj.fileWrite("test") sul server, ed 
>obj.getText sul client, metodo che fa altro, inesistente sul server, come è 
>inesistente fileWrite sul client (methodTable decide cosa trasportare e cosa 
>no)

Cosa c'entra? Non puoi trasportare i metodi. Devi scriverli i metodi.

>Stessa classe, stesso stato, metodi uguali con o senza lo stesso nome con 
>possibilità di usare operazionidifferenti a seconda dell'utilizzatore, 
>client o server.
>Poi in realtà ACE permette anche questo ma si basa sulla semplicità ... 

Permettimi ma non posso che dissentire, di semplice il modello non ha nulla.

>quindi se vuoi mandargli un metodo della classe Pippo di nome sayHello in 
>ACE senza alzare un dito avrai la possibilità di fare
>
>var p = new Pippo();
>p.sayHello.call();
>p.sayHello.result = function(str){alert(str)}
>fine, volendo hai anche
>p.sayHello.progress = function(perc){alert(perc)}
>per avere un riscontro in percentuale della ricezione dei dati

E` tremendo. Quindi io posso accedere a tutti gli oggetti che voglio lato
client facendo quello che desidero attraverso quegli oggetti? Che poi e` molto
poi semplice fare una cosa tipo:

callRemote("sayHello").addCallback(function(str) {alert(str)})

oppure

function progress(perc) {alert(perc)}

lasciando al server il compito di chiamare perc quando necessario senza scomodare
il client.

>>Decisamente non sai cosa siano gli encoding...
>... decisamente non ci capiamo ...
>>Perche` e` assurdo che la stringa di byte (ovvero una stringa di testo 
>>codificata in utf-8) debba ritornare i caratteri e non la lunghezza?
>e chi l'ha mai detto ? Io ho solo detto che è una pecurialità di php e php 
>"soltanto" ed è la causa del rallentamento in serializzazione / 
>unserializzazione con JS o gli altri linguaggi quando devi interagire con il 
>formato serializzato di php abilitando il supporto UTF-8
>
>         def __slen(self, s):
>                 charcode = 0
>                 result = 0
>                 slen = len(s)
>                 if self.UTF8:
>                         while slen:
>                                 slen = slen - 1
>                                 try:
>                                         charcode = ord(s[slen])
>                                 except:
>                                         charcode = 65536
>                                 if charcode < 128:
>                                         result = result + 1
>                                 elif charcode < 2048:
>                                         result = result + 2
>                                 elif charcode < 65536:
>                                         result = result + 3
>                                 else:
>                                         result = result + 4
>                 else:
>                         result = slen
>                 return result

charcode non sara` mai piu` di 256 a meno che s non sia unicode perche` per ottenere
piu` di 256 ti serve un carattere multibyte che non otterrai mai senza usare unicode.

>>> [ord(x) for x in "ˀ߯ßð¯ßð¯ßʼø,-≤˛©ˍˇ®þ¸´®þ®¶ʼ¥,øʼ…˝-˚"]
[203, 128, 195, 159, 194, 175, 195, 159, 195, 176, 194, 175, 195, 159, \
195, 176, 194, 175, 195, 159, 202, 188, 195, 184, 44, 45, 226, 137, 164, \
203, 155, 194, 169, 203, 141, 203, 135, 194, 174, 195, 190, 194, 184, 194, \
180, 194, 174, 195, 190, 194, 174, 194, 182, 202, 188, 194, 165, 44, 195, \
184, 202, 188, 226, 128, 166, 203, 157, 45, 203, 154]
>>> len("ˀ߯ßð¯ßð¯ßʼø,-≤˛©ˍˇ®þ¸´®þ®¶ʼ¥,øʼ…˝-˚")
70
>>> len(u"ß")
1
>>> ord(u"ß")
223
>>> ord("ß")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: ord() expected a character, but string of length 2 found
>>> ord("ß"[0])
195
>>> ord("ß"[1])
159
>>> ord(u"˝")
733
>>> len("˝")
2
>>> ord("˝"[0])
203
>>> ord("˝"[1])
157

>Ecco cosa tocca fare in JS come in Python (almeno credo sia così, 
>illuminatemi altrimenti) per ritrovare la len "fasulla" del PHP

Non c'e` nessuna len fasulla.

>L'assurdo non è la stringa in byte , l'assurdo è che non c'è modo di non 
>avere la stringa in bytes.

Assolutamente sbagliato e questo perche` non conosci gli encoding.

>>> len(unicode("ˀ߯ßð¯ßð¯ßʼø,-≤˛©ˍˇ®þ¸´®þ®¶ʼ¥,øʼ…˝-˚", "utf-8"))
36
>>> len("ˀ߯ßð¯ßð¯ßʼø,-≤˛©ˍˇ®þ¸´®þ®¶ʼ¥,øʼ…˝-˚")
70

>cmq noi piaccapari ignoranti e biasimati parliamo di questa "caratteristica 
>assurda" da talmente tanto tempo che in PHP6 da mesi si parla di colmare le 
>problematiche con UTF-8 ... ed infatti hanno messo nativamente UTF-16 (LOL)

Ma il problema non lo risolverete ancora :).

>cmq ho scritto che mi ero sbagliato, so che sono differenti anche se non so 
>bene quanto non essendomi mai posto il problema

Ora pero` sei obbligato a portelo perche` in python questo problema non e`
nascosto goffamente dal linguaggio ma ti viene sbattuto in faccia facilmente.

>Il nesso è la portabilità della lib, ma a quanto pare avete già 
>l'onnipotenza in materia e quindi una lib che con una sola scrittura del 
>client si porta anche in Python, oltre che PHP e C# non vi interessa.

Ma esiste gia` JSON, chissenefrega di una libreria usata in php perhe` in php
JSON e` lento come la fame?

>Strano, nell' era del "web js & ajax" avere librerie da non dover riscrivere 
>anche per il client dovrebbe muovere l'interesse collettivo, proverò con gli 
>altri linguaggi, abbandono il porting per Python ? Visto che tutto è inutule 
>e che non si capisce niente dell'intento o le potenzialità della libreria 
>devo proprio aver cannato linguaggio ...

Esiste gia` JSON, negli altri linguaggi dubito verrai accolto molto differentemente.

Se vuoi scrivere la tua libreria in python perche` serve al tuo progetto nessuno
te lo impedisce ma e` difficile trovarne l'utilita` quando c'e` gia` JSON che
funziona ed e` _gia`_ implementato in tanti linguaggi e la tua libreria non
porta vantaggi di alcun genere per questo scopo.

>>Io lo faccio gia` usando json, e lo fanno tantissimi altri developer 
>>python. Che ne dici di evitare di pensare a python come a quel accrocchio 
>>di php?
>Che ne dici di evitare di valutare ancora prima di conoscere ?

PHP lo conosco abbastanza da evitarlo direi e le ultime cose che mi hai detto su
JSON non fanno altro che confermare le mie conoscenze su PHP :).
Per quanto riguarda te non mi sono mai permesso di esprimere valutazioni sulla
tua intelligenza o professionalita`.

>si, non è compatibile con le stringhe UTF-8 , invia liste, tuple e dict e 
>ritorna sempre e solo dict, non invia ne riceve Classi.

Perche` non si possono ne` inviare ne` ricevere classi ma solo il loro stato il
che significa inviare un dict (che se proprio uno vuole farsi del male
e` self.__dict__).

>Che ne dici di dare una guardata alla mia di classe ? Che riceve anche 
>liste, gestisce utf-8 e classi ?

Non mi spiacerebbe ma l'ultima volta che l'ho fatto il risultato e` stato
disastroso per cui prima mi firmi un documento che ti impedira` di farmi causa
se la mia reazione sara` vigorosa, poi guardo il tuo sorgente.

>Tra l'altro il tizio della serialize "che esiste già" mi ha già fatto i 
>complimenti ed ha detto che quanto prima avrebbe aggiornato il suo sito per 
>segnalare la variante.

E chi e` il tizio?

>Il tizio non ha fatto una versione per PyRex ... ma questa che razza di ml 
>python è ? Open Source, Closed Eyes, Every Other Out of Here ?

Si. Pero` a me piace questo modo di comprendere l'open source dove non esiste
discussione, se io ho un'idea e` giusta per forza perche` e` un'altra idea, non
c'e` la possibilita` che sia sbagliata o che meriti una discussione in cui
l'autore si trova a difendere le sue scelte progettuali. Semplicemente va
accettata e ci si riempie tutti di pacche sulle spalle perche` siamo stati
bravi a creare l'ennesima variante di una libreria che esiste gia`.

>va bene, stravolgiamo le convinzioni mondiali sull'utilità del delegare 
>parte dei calcoli al client in ambito web perchè Gmail su un K6 non gira 
>bene (ma poi Gmail ha una miriade di codice, la lib invece pesa 15 Kb con 3 
>classi incluse di cui 2 riutilizzabili, JSL e PHP_Serializer ... ah no, 
>tutto inutile ...).

A me spiace che una discussione in cui non ho alzato i toni e sto cercando di
capire e consigliare i motivi delle tue scelte sta diventando per te una questione
personale.

>Per quale motivo sarebbe uno sforzo inutile ??? ... ammesso che a te non 
>importi niente di questa versione, perchè io dovrei farne a meno ?

Ma tu puoi scriverla come ti pare, te lo sto impedendo in qualche modo? Magari
ti sfugge che stiamo discutendo di una tua libreria e riguardo alle tue scelte
di inventare un nuovo formato di serializzazione che non aggiunge nulla a
JSON (non e` piu` semplice da parsare, non e` piu` veloce in Python se sia
il tuo che l'altro li si implementa in Pyrex [ma se nessuno ha implementato
json in C/pyrex/boost/altro significa che non e` un problema per nessuno]).
Nasconde semplicemente il procedimento di serializzazione di oggetti arbitrari
che non va nascosto per varie ragioni che spieghero` solo se avrai voglia
di discutere invece che prenderla sul personale.

>>A giudicare da quello che hai scritto sopra direi che il problema e` piu` 
>>che un errore semplice.
>Si, come dici tu

Gli encoding hai ammesso di non conoscerli perche` con php non ti sei mai posto
il problema... Ora fai l'ironico a riguardo?


Maggiori informazioni sulla lista Python