Articoli Manifesto Tools Links Canali Libri Contatti ?
Linguaggi / Python

Python: un'introduzione

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
di Giovanni Giorgi Discuti sul forum   Stampa

Introduzione a Python

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.
>>> l=['una','bella']
>>> l[1:1]=[ 'lista', 'molto']
>>> print l
['una', 'lista', 'molto', 'bella']
>>>
Le liste possono contenere elementi eterogenei.

Tuple e array associativi

Come in Perl, sono provvisti gli array associativi.
Esempio:
>>> as={'gio': 'Bello', 'Guido': 'Brutto'}
>>> print as['gio']
Bello
>>> as.keys()
['Guido', 'gio']
>>>

Indentazione dei cicli for, delle condizioni ecc

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:
  1. def printMsg(messaggio): 
  2.     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:
  1. datovario=1+2 
  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:
$ python rdfparser.py  -fm
Python RDF Script Rev $id$
RDF Parser
Giovanni Giorgi rdfparser@objectstoot.com
Fetching RDF. from URL:http://freshmeat.net/backend/fm.rdf
Parsing...
Site Title:freshmeat.net
News Title:dhcp-dns 1.04
 http://freshmeat.net/releases/97048/
News Title:getID3() 1.4.2
 http://freshmeat.net/releases/97046/
News Title:sipsak 0.7.5
 http://freshmeat.net/releases/97045/
News Title:Logrep 1.0
 http://freshmeat.net/releases/97023/
News Title:psycopg 1.0.12 (Stable)
 http://freshmeat.net/releases/97041/
News Title:GnuPoc Pre-Alpha
 http://freshmeat.net/releases/97020/
News Title:PowerMail 1.4
 http://freshmeat.net/releases/97040/
News Title:GNU Smalltalk 2.0c (Development)
 http://freshmeat.net/releases/97039/
News Title:GNU Smalltalk 2.0.6 (Stable)
 http://freshmeat.net/releases/97038/
News Title:Missile Command 1.0.0
 http://freshmeat.net/releases/97037/
===================
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:
  1. printIntro() 
  2. rdfurl="" 
  3. opts={ "-fm":"http://freshmeat.net/backend/fm.rdf", 
  4.        "-or":"http://freezope2.nipltd.net/gio/jj/JDot/rdf", 
  5.        "-debug":"http://localhost:8080/freezopeSiteBackup/JDot/rdf" 
  6. if len(sys.argv)<=1: 
  7.     print "Usage:" 
  8.     print __doc__ 
  9. else: 
  10.     if sys.argv[1] == "-last": 
  11.         rdfurl='' 
  12.         print "Reading last" 
  13.         f=open("lastrdf.xml","r") 
  14.         text=f.read() 
  15.         f.close() 
  16.     else: 
  17.         # Opzioni diverse da -last 
  18.         if opts.has_key(sys.argv[1]):         
  19.             rdfurl=opts[sys.argv[1]] 
  20.         else: 
  21.             # Interpretato come URL 
  22.             rdfurl=sys.argv[1]                     
  23.         print "Fetching RDF. from URL:"+rdfurl    
  24.         f = urllib.urlopen(rdfurl) 
  25.         text=f.read() 
  26.         lastf=open("lastrdf.xml","w") 
  27.         lastf.write(text) 
  28.         lastf.close()                 
  29.     #For debug only:     
  30.     ###print text 
  31.     print "Parsing..." 
  32.     dom = xml.dom.minidom.parseString( text ) 
  33.     handleRDF(dom) 
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:
  1. dom = xml.dom.minidom.parseString( text ) 
  2. 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():

  1. def getText(nodelist): 
  2.     """ Parse a String """ 
  3.     rc = "" 
  4.     for node in nodelist: 
  5.         if node.nodeType == node.TEXT_NODE: 
  6.             rc = rc + node.data 
  7.     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.

È possibile consultare l'elenco degli articoli scritti da Giovanni Giorgi.

Altri articoli sul tema Linguaggi / Python.

Risorse

  1. Il sorgente del parser rdf illustrato dall'articolo.
    http://www.siforge.org/articles/2002/09/python-intro/rdfparser.py (3Kb)
  2. L'rdf usato negli esempi.
    http://www.siforge.org/articles/2002/09/python-intro/lastrdf.xml (2Kb)
  3. Il sito ufficiale di Python.
    http://www.python.org/
  4. Tutorial per apprendere il linguaggio partendo da zero.
    http://www.python.org/doc/current/tut/tut.html
  5. RDF Site Summary (RSS) 1.0
    http://groups.yahoo.com/group/rss-dev/files/specification.html
  6. Specifica del formato RDF come da W3C
    http://www.w3.org/RDF/
  7. Descrizione tecnica del formato rdf
    http://developer.netscape.com/tech/rdf/rdf.html
  8. Link ulteriore alla specifica RSS
    http://my.netscape.com/publish/formats/rss-0.91.dtd
Discuti sul forum   Stampa

Cosa ne pensi di questo articolo?

Discussioni

Questo articolo o l'argomento ti ha interessato? Parliamone.