Abstract
In questo articolo introduciamo il lettore al linguaggio Python
versione 2.1. Come esempio, mostreremo un programma in grado di
leggere il formato XML RDF, disponibile presso molti siti (per es
FreshMeat).
Data di stesura: 01/09/2002
Data di pubblicazione:
01/09/2002
Ultima modifica: 04/04/2006
Lo scopo di questo articolo è introdurre il lettore all'uso del
linguaggio python. È propedeutica la conoscenza di un altro linguaggio di
programmazione come il C o Java.
Per maggiori informazioni vi consigliamo di fare riferimento
all'ottimo Python Tutorial[4] disponibile on line sul sito di python.
Seguiranno altri articoli, in cui mostreremo esempi via via più complessi.
Breve storia di Python
Python
nasce intorno al 1990 ad opera di Guido van
Rossum presso lo Stichting Mathematisch Centrum (CWI) in Olanda.
Dopo un lungo periodo di incubazione, python inizia a diffondersi nel 2000.
Guido van Rossum lavora prima presso BeOpen.com e poi va alla
Digital Creations, ove verrà sviluppato
Zope
un grosso progetto scritto in Python, a cui però Van Rossum non
parteciperà direttamente.
Si tratta di un linguaggio di scripting general purpose, in licenza
Open Source (ma non GNU GPL).
Python include un nutrito set di librerie, e può funzionare sia come
linguaggio ad oggetti che come semplice linguaggio funzionale.
Contrariamente a Perl non è orientato ad uno scopo particolare, ed ha
un set di librerie simili a quelle di PHP, per quanto riguarda la
capacità di gestire i protocolli internet base (FTP, HTTP, POP, SMTP,
NNTP, ecc).
Da qui in avanti si supporrà cha abbiate
scaricato
ed installato la versione 2.2 o 2.1 di python. Sotto Unix, è necessario che
installiate anche le librerie di parsing dell'XML
(expat) affinchè
l'esempio dell'rdf parser[1] funzioni
correttamente.
Il primo programma: hello world o quasi
Lanciate l'interprete python, digitando dalla shell python.
Da windows usate il command.com/cmd.exe oppure cliccate sulla sua
icona di "Python (command line)".
Digitate print 'Ti stampo' e premete invio.
L'output sarà del tipo:
Python 2.1.3 (#35, Apr 8 2002, 17:47:50) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>> print 'Ti stampo'
Ti stampo
>>>
In python il fine linea è un separatore di comandi (come in BASIC).
I commenti vanno preceduti dal cancelletto (#).
Le variabili possono essere usate senza dichiarazione, per esempio:
>>> a=7*8
>>> print a
56
>>>
Oltre alle stringhe, tra i tipi base ci sono le liste che sono
strutture dinamiche.
Durante un assegnamento, si includono tra parentesi quadrate gli
elementi di una lista, separandoli con virgole.
La prima cosa che si nota usando Python è che l'indentazione dei
blocchi di codice è indispensabile e richiesta dalla sintassi del
linguaggio.
Benché questa costrizione formale limiti la nostra libertà, ci
garantisce sempre una indentazione uniforme.
Per esempio, il seguente codice:
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print i, a[i]
...
ritorna:
0 Mary
1 had
2 a
3 little
4 lamb
Strutture di controllo e funzioni
Copiate il seguente script e lanciatelo:
#!/usr/bin/env python
"""
Auto Documentazione: qui descrivo cosa fa lo script
"""
import sys
import os
import string
if len(sys.argv)<=1:
print "Usage:"
print __doc__
else:
print "Primo parametro:"+sys.argv[1]
Senza parametri viene stampato:
Usage:
Auto Documentazione: qui descrivo cosa fa lo script
Invece passando per es il parametro Pluto, viene stampato "Primo parametro:Pluto".
Python assegna automaticamente alla variabile speciale "__doc__" il
contenuto della stringa letterale dichiarata prima del codice. Anche
le funzioni hanno questa possibilità.
Dichiarazione delle funzioni
La dichiarazioni delle funzioni è fatta usando una sintassi del tipo:
def printMsg(messaggio):
print " Log:"+messaggio
Fare sempre attenzione alla identazione.
Esempio d'uso di chiamata della funzione printMsg():
>>> printMsg("Esempio di parametro " + " formale")
Log:Esempio di parametro formale
>>>
Osservate che python supporta la tipizzazione dinamica, per cui è possibile
scrivere:
datovario=1+2
datovario="Ora sono una stringa"
Per questa ragione quando si dichiara una funzione, non è necessario
specificare il tipo dei parametri.
Qualcosa di più utile
Il formato RDF[6] è un
dtd XML per descrivere il contenuto di un sito. Come tale è una
specie di meta-XML che dice come vanno descritti...gli XML che
descrivono i siti.
In particolare, il formato RSS[5]
è una "XML application" dell'RDF.
RSS è stato introdotto nel 1999 dalla Netscape per descrivere i
"canali" (channels) usati nel browser Netscape Communicator.
Attualmente l'RSS è usato da molti siti, e ci sono dei programmi in grado
di visualizzarne il contenuto.
Ecco un esempio di file rdf che segue la specifica rss:
<?xml version="1.0" encoding="ISO-8859-1"?> <rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://my.netscape.com/rdf/simple/0.9/" >
<channel>
<title>freshmeat.net</title>
<link>http://freshmeat.net/</link>
<description>freshmeat.net maintains the Web's largest index of
Unix and cross-platform open source software. Thousands of
applications are meticulously cataloged in the freshmeat.net database,
and links to new code are added daily.</description>
</channel>
<image>
<title>freshmeat.net</title>
<url>http://images.freshmeat.net/button.gif</url>
<link>http://freshmeat.net/</link>
</image>
<item>
<title>Java Topology Suite 1.1 (Stable Release)</title>
<link>http://freshmeat.net/releases/97062/</link>
</item>
<item>
...
<textinput>
<title>Search freshmeat.net</title>
<description>Search freshmeat.net projects</description>
<name>q</name>
<link>http://freshmeat.net/search/</link>
</textinput>
</rdf:RDF>
Uso del parser
Scaricate l'rdfparser.py[1].
Senza sconnettervi da Internet, provate a lanciarlo con qualcosa del tipo:
In questo esempio il parser rdf si è collegato al sito di
freshmeat.net e ha scaricato la lista degli ultimi programmi rilasciati.
Inoltre il parser salva in un file di nome "lastrdf.xml" l'ultimo rdf
scaricato.
Per rieseguire il parsing senza connettersi a internet, potete usare
il comando python rdfparser.py -last.
Il programmino tenterà di leggere il file lastrdf.xml.
L'XML contiene molte più informazioni di quelle che vengono
presentate, in quanto questo script serve solo da esempio.
Python consente di programmare sia ad oggetti che in modo
funzionale. Per semplicità questo script è composto da una serie di
funzioni che sfruttano le classi del DOM XML e della urllib.
È possibile consultare la reference completa delle classi usate sul sito di
python.
Analizziamo ora lo script, linea per linea.
Parsing delle opzione di input
Il main è identificabile dal commento "MAIN" intorno a linea 65 e
presenta il seguente codice:
In python non c'è bisogno di dichiarare le variabili, ma non è
possibile usarle se esse sono indefinite.
Per cui per prima cosa assegnamo la stringa vuota alla variabile
rdfurl per garantire che esista.
Successivamente inizia un semplice parsing dei parametri di input.
Se un parametro non viene riconosciuto come opzione viene interpretato come
url.
Provate per esempio:
python rdfparser.py "http://diveintomark.org/xml/rss.xml".
Ottenimento dell'url
L'url viene scaricato solo se non si usa l'opzione -last.
La funzione urllib.urlopen() fa tutto il lavoro per noi, e ci ritorna
uno stream, che possiamo leggere come se fosse un file.
Per prima cosa il testo letto viene salvato nel file lastrdf.xml e poi
analizzato.
Notate la semplicità di queste operazioni: si assegna ad una
variabile l'intero contenuto dell'url (linea 26).
Parsing dell'XML
Il parsing dell'XML viene effettuato costruendo l'albero di parsing e
poi stampandolo:
dom = xml.dom.minidom.parseString( text )
handleRDF(dom)
xml.dom.minidom.parseString() ritorna un'istanza di
xml.dom.Document.
La funzione handleRDF() si preoccupa di leggere l'rdf,
prendendo solo le parti che interessano.
Per funzionare handleRDF si serve del metodo
getElementsByTagName(tagName) che, dato un tag name,
ritorna un array di oggetti Node con quel nome.
L'oggetto xml.dom.Node possiede la proprietà
childNodes che ritorna i suoi nodi "figli".
Per stampare i nodi terminali, che contengono del testo, ci si
serve della funzione di appoggio getText():
def getText(nodelist):
""" Parse a String """
rc = ""
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
return rc
Conclusioni
In questo primo articolo abbiamo appreso come scrivere uno script in
python, definire delle funzioni e usare le librerie ad oggetti fornite
con il linguaggio. Nel prossimo articolo vedremo come programmare ad oggetti.
Informazioni sull'autore
Giovanni Giorgi, classe 1974. Dopo il diploma di liceo Classico, si è laureato in Informatica nel febbraio 2000, e attualmente lavora nel campo del software finanziario (trading on line, soluzioni web). Appassionato di linguaggi di programmazione, si interessa anche di politica e letteratura.