SlideShare ist ein Scribd-Unternehmen logo
1 von 94
Introduzione al
Linguaggio Python
Enrico Franchi
efranchi@ce.unipr.it
Dipartimento di Ingegneria dell'Informazione
Università di Parma                            1
Parlando del
futuro...                               2
We will perhaps eventually be
writing only small modules that are
identified by name as they are
used to build larger ones, so that
devices like indentation, rather than
delimiters, might become feasible
for expressing local structure in the
source language.

Donald E. Knuth, Structured
Programming with go to
Statements, 1974
Introduzione                                                 3

 Python è concepito da Guido van Rossum alla fine
 degli anni ‘80 per Amoeba
 Pubblico 1991, stabile 1994.
 Linguaggio di alto livello ed orientato agli oggetti.
 Utilizzato per programmazione di sistema e di rete, e
 calcolo scientifico, applicazioni desktop, integrazione di
 videogiochi
 Si impone in ambito web/enterprise, con soluzioni
 come Zope/Plone, Django e Twisted.
Piattaforma Python                                  4

 “Very high-level language” (VHLL):
   sintassi pulita e scarna
   semantica semplice, regolare, potente
   object-oriented, ma multi-paradigma
   produttività tramite: modularità, uniformità,
   semplicità, pragmatismo
 Offre una ricca libreria standard di moduli
 Tanti strumenti ed estensioni di terze-parti
 Implementazioni in C, Java, .NET e Python stesso
Comunità Python                                               5

Una forte comunità open-source
Molti utenti (individui e compagnie) in tutti i campi
Python Software Foundation (in Italia, Python Italia)
Gruppi d’interesse per argomenti specifici
Siti web, newsgroup, mailing list, ...
Corsi, laboratori, tutorial, conferenze (Pycon Italia,
quattro edizioni, fra le maggiori conferenze open italiana)
  Molti (specialmente in inglese...) in linea, su carta, o
  entrambi
MESSAGGIO PROMOZIONALE
                                                6




              7-8-9 MAGGIO 2010
                    FIRENZE

SCONTO STUDENTI, SESSIONI RECRUITING, ETC ETC
             http://www.pycon.it

               ~400 partecipanti
Tempi di Apprendimento                                           7

Tempi necessari a un programmatore esperto per
imparare bene...:
  Python vero e proprio (il linguaggio Python): 1-3 giorni
  builtin, metodi speciali, metaprogramming, ecc: 2-4 giorni
  la libreria standard (moduli fondamentali: os, sys, re,
  struct, itertools, collections, array, atexit, math, pickle,
  StringIO, heapq, weakref, threading...): 10-15 giorni
  tutta la libreria std: 30-50 giorni
Python da 3000 metri (1)                                     8

 Python è un linguaggio ad oggetti a tipizzazione
 dinamica e forte
   Tipizzazione forte:
     Gli errori di tipo sono sempre generati. Es. Stringhe
     non diventano interi e viceversa
     Ogni oggetto ha una classe, questa non cambia
   Tipizzazione dinamica
     Gli errori di tipo sono generati a runtime
     Duck typing
Python da 3000 metri (II)                      9

 In Python tutto è un oggetto:
   Un numero, una stringa sono oggetti
   Gli oggetti sono oggetti (ehm...)
   Una funzione è un oggetto
   Una classe è un oggetto
 Gli oggetti sono cittadini di prima classe,
 possiamo manipolarli riccamente e
 comodamente (introspezione, etc.)
 Possiamo fare, in definitiva, tutto
Versioni                                              10

 Python è notevolmente compatibile fra versioni
 diverse
 Gli esempi di queste slides funzioneranno con
 Python 2.5 o Python 2.6, a meno che altrimenti
 specificato
   La maggior parte funzioneranno anche con
   Python 2.4 e Python 2.3
 Python 3.x rappresenta il futuro, ma per ora si
 utilizza ancora 2.x, la transizione sarà morbida e
 lunga anni
Hello, world!            11




 print
“Hello,
world!”
Dettagli implementativi                                    12

                                % cat hello.py
 Tipicamente Python viene       #!/usr/bin/python
 compilato a byte-code e
 questo viene interpretato da   print "Hello, world!"
 una macchina virtuale (come
                                % python hello.py
 Java)                          Hello, world!
 Diversamente da Java la        % chmod 755 hello.py
                                % ./hello.py
 compilazione è trasparente     Hello, world!
 per l’utente                   % python
                                Python 2.5.1 (...)
 Possiamo anche usare           ...
 l’interprete interattivo       >>> print "Hello, world"
                                Hello, world
Interprete interattivo                                                   13

 L’interprete interattivo ufficiale ha
                                        >>> import os
 come prompt >>>                        >>> print “foo”
                                        foo
 Scriviamo comandi (statements)         >>> os.getcwd()
                                        “/Users/enric/pycourse”
 che vengono byte-compilati ed          >>> import sys
                                        >>> sys.stdout.write(“ciaon”)
 eseguiti                               ciao
                                        >>> def f(a):
 Se il comando valuta in un             ...  sys.stdout.write(a)
                                        ...  return a
 espressione (es. un expression         ...
 statement), l’espressione viene        >>> f(“ciaon”)
                                        ciao
 stampata                               “ciaon”
Letterali                                                                     14

                                    >>> 12            >>> 3.2E10
 Numeri interi, float                12                32000000000.0
                                    >>> -27           >>> 'ciao'
   Base 10, 8, 16                   -27               'ciao'
                                    >>> 0x6A          >>> "ciao"
   Scientifica, fixpoint              106               'ciao'
                                    >>> 0.216         >>> 'c'
                                    0.216             'c'
 Stringhe
                                    >>> [1, 2, "a", 2.32, "ciao"]
   Apici singoli o doppi            [1, 2, 'a', 2.3199999999999998, 'ciao']
                                    >>> '''Testo con
   Tre apici per testo multilinea   ... piu' linee
                                    ... di testo'''
 Liste                              "Testo connpiu' lineendi testo"
                                    >>> """Ancora testo con
                                    ... piu' linee di testo"""
   Fra quadre, separate da          "Ancora testo connpiu' linee di testo"
   virgola
a = 16
                                                          print a
                                                          a = 7.6


Variabili
                                                          print a
                                                          print a * 2
                                                          a = 'ciao'
                                                                        15

                                  i=1
 In Python una variabile è        print i, type(i)
 semplicemente un nome, un’       # => 1 <type 'int'>
                                  d = 217.217
 etichetta, un modo per           print d, type(d)
                                  # => 217.217 <type 'float'>
 riferirsi ad un oggetto          s = '''Solito testo
                                  su piu' righe'''
 Le variabili non hanno tipo,     print s, type(s)
                                  # => Solito testo
 gli oggetti hanno tipo           # su piu' righe <type 'str'>
                                  d=2
 Una etichetta può riferirsi ad   print d, type(d)
                                  # => 2 <type 'int'>
 oggetti di diverso tipo nel      i = 32761293836219387269827
                                  print i, type(i)
 tempo                            # => 32761293836219387269827 <type
                                  'long'>
 Assegnamento è statement
Variabili/Oggetti                                      16

  [java] Pet fido = new Dog();
tipo a compile-time                  tipo a runtime
                           oggetto    (dell’oggetto)
   (della variabile)

               variabile



  [python] fido = Dog()
Controllo di flusso                                     17

 Condizionale:           Su if c’è poco da dire; while si
    if cond:             usa rarissimamente, grazie ai
    statement
 else:                   generatori si preferisce for
    statement
                         Siccome l’assegnamento è uno
 if cond:
     statement           statement, non è possibile
 Iterazione unbounded:   metterlo come condizione
  while cond:
   statement
                         (fortunatamente)
else:                    Disponibili break/continue
   statement
                         else di for/while esegue su
while cond:
  statement
                         terminazione naturale (no exc/
                         cont/break/return)
Liste (I)                                                              18

                                   >>> a = [1, 2, 'a', 'ciao', 4]
 La lista è in realtà un vector:   >>> a[0]
                                   1
 accesso O(1) agli elementi        >>> a[3]
                                   'ciao'
 Inserimento e rimozione in        >>> a[-1]
                                   4
 coda O(1)                         >>> a[10]
                                   Traceback (most recent call last):
 Controllo sugli indici              File "<stdin>", line 1, in <module>
                                   IndexError: list index out of range
 (IndexError)                      >>> a.append(3)
                                   >>> a
 Indici negativi contano a         [1, 2, 'a', 'ciao', 4, 3]
                                   >>> l = range(1, 4)
 partire dal fondo                 >>> a.extend(l)
                                   >>> a
 Possibilità di slice              [1, 2, 'a', 'ciao', 4, 3, 1, 2, 3]
                                   >>> a.pop()
                                   3
Liste (II)                                                            19
                                  >>>   a
 Presenti anche:                  [1,   2, 'a', 'ciao', 4, 3, 1, 2]
                                  >>>   a[1:4]
   insert(i, o): inserisci o in   [2,
                                  >>>
                                        'a', 'ciao']
                                        a[1:8:2]
   posizione i                    [2,   'ciao', 3, 2]
                                  >>>   a[::-1]
   remove(v): togli la prima      [2,   1, 3, 4, 'ciao', 'a', 2, 1]
                                  >>>   a
   occorrenza di v                [1,   2, 'a', 'ciao', 4, 3, 1, 2]

   count(v): ...
   index(v): ...
   sort(): ...
   ...
 Le liste sono mutabili
Tuple                                                                     20

                                     >>> t = tuple(a)
 “Simili” alle liste, tuttavia non   >>> t[3]
                                     'ciao'
 sono mutabili                       >>> t[-1]
                                     2
   Non possiamo aggiungere           >>> t[1:]
                                     (2, 'a', 'ciao', 4, 3, 1, 2)
   elementi                          >>> a, b, c = t[:3]
                                     >>> print a, b, c
   Non possiamo cambiare             1 2 a
   elementi nella tupla              >>> t = 1, 2, 'x'
                                     >>> l = list(t)
   Possiamo agire su questi, se      >>> t.append(5)
                                     Traceback (most recent call last):
   non sono immutabili                 File "<stdin>", line 1, in <module>
                                     AttributeError: 'tuple' object has no attribut
   Per il resto funziona tutto       >>> l.append(5)
                                     >>> l
   come previsto                     [1, 2, 'x', 5]
Stringhe                                                                21

 Anche le stringhe sono          >>> s = 'Hello, world!
                                 >>> s.strip()
                                                          '

 immutabili (= Java, != C++)     'Hello, world!'
                                 >>> s.replace('o', '0')
                                 'Hell0, w0rld!   '
 Supportano slicing, indexing,   >>> s.find('o')
 etc.                            4
                                 >>> s.rfind('o')
                                 8
 isdigit(), ...                  >>> s.upper()
                                 'HELLO, WORLD!   '
 strip()...                      >>> s.center(60)
                                 '                      Hello, world!
 find/rfind/index/rindex(ch)       >>> s.startswith('He')
                                 True
                                 >>> s.split(', ')
 startswith/endswith(s)          ['Hello', ' world!   ']

 upper/lower/capitalize()        ... andate a guardarli tutti!
Operazioni su sequenze                                              22
                                >>> s = 'ciao'
 Stringhe, tuple e liste sono   >>> m = 'mondo'
                                >>> min(s) # <= 'a'
 sequenze                       >>> max(m) # <= 'o'
                                >>> l = [1, 2, 3]
 Tutte le sequenze supportano   >>> sum(l) # <= 6
                                >>> s + m # <= 'ciaomondo'
 alcune operazioni              >>> s + l
                                Traceback (most recent call last):
 min/max/sum                      File "<stdin>", line 1, in <module>
                                TypeError: cannot concatenate 'str' and 'list'
                                >>> list(s) + l
 +   : concatenazione           ['c', 'i', 'a', 'o', 1, 2, 3]
                                >>> '=' * 10
 S * n/ n * S: ripetizione      '=========='
                                >>> [1, ] * 10
 el in S: appartenenza          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
                                >>> 'a' in s
                                True
                                >>> 'pippo' in l
                                False
Attenzione!                                                            23

 Sommare tanti oggetti immutabili funziona, ma crea ogni volta un
 nuovo elemento:
   Sommare 10 stringhe crea 10 nuove stringhe. E se sono 10000?
   Potrebbe essere l’ultimo pezzo di codice prima del licenziamento.
   Si usa join nella forma sep.join(elements)
   >>> lst = ['usr', 'local', 'lib']
   >>> '/'.join(lst)
   'usr/local/lib'
   >>> ' => '.join(lst)
   'usr => local => lib'


 Per concatenare pezzi di path, usare os.path.join e i metodi
 presenti in os.path
Statement For                                                       24

 For è il modo più comune di     for ch in 'ciao mondo':
                                     print ch,
 iterare in Python               print

                                 for n in range(10):
   Funziona con un generico          print n
   iterabile                     for n in xrange(10):
                                     print n
   Esprime il concetto di “per   for n in range(1, 20):
   ogni elemento in questa           print n
                                 for n in xrange(1, 10000000000):
   sequenza” fai qualcosa            print n

   Invece che usare una
   sequenza (finita), possiamo
   usare un generatore
   (potenzialmente infinito)
Statement For                                                        24

 For è il modo più comune di     for ch in 'ciao mondo':
                                     print ch,
 iterare in Python               print

                                 for n in range(10):
   Funziona con un generico          print n
   iterabile                     for n in xrange(10):
                                     print n
   Esprime il concetto di “per   for n in range(1, 20):
   ogni elemento in questa           print n
                                 for n in xrange(1, 10000000000):
   sequenza” fai qualcosa            print n

   Invece che usare una
   sequenza (finita), possiamo      Attenzione! range ritorna
   usare un generatore             una lista xrange un iteratore.
   (potenzialmente infinito)        Restituiscono intervalli [a, b)
99 Bottles of Beer                                            25



def pluralize(s, quantity):
    if quantity == 1:
        return s
    else:
        return s + "s"

for how_many in range(99, 0, -1):
    print how_many, pluralize("bottle", how_many), "on the wall!"
    print "Take one down and pass it around,", how_many-1,
    print pluralize("bottle", how_many-1),
    print "of beer on the wall."
More on for...                                    26




     import os
     import shutil

     for fname in os.listdir(os.getcwd()):
         if fname.endswith(('pyc', 'pyo')):
             os.remove(fname)
         elif fname.endswith('py'):
             shutil.copy(fname, fname + '.bak')
Dizionari                                                            27

 Array associativi/dizionari:    >>> d = {'foo' : (1, 2, 3),
                                 ...       'bar' : (2, 3, 4)}
 coppie chiave-valore            >>> d['foo']
                                 (1, 2, 3)
   Operazioni tipicamente O(1)   >>> d['baz']
                                 Traceback (most recent call last):
                                   File "<stdin>", line 1, in <module>
   Implementazione               KeyError: 'baz'
   esageratamente efficiente      >>> d['bar'] = 'foo'
                                 >>> d
                                 {'foo': (1, 2, 3), 'bar': 'foo'}
 La chiave deve essere
 hashabile e immutabile (ecco
 perchè le stringhe...)
 Essenzialmente è una hash-
 table
Dizionari (altri metodi)                                28

 D.pop(k[, d]): rimuove   k (se presente)
 restituendo il valore corrispondente. Altrimenti
 restituisce d se specificato o da AttributeError
 D.popitem(): ritorna   una coppia k-v (qualsiasi)
 D.get(k[,d]): ritorna il valore di k o d se k non è
 presente. Se non specificato d vale None.
 D.setdefault(k[,d]): D.get(k,d), setta D[k]=d
 se k non è in D
 D.update(E, **F): aggiunge    le coppie k-v di E (ed
 F) a D
Format (printf-on-steroids)                                                                     29

 Le stringhe hanno un operatore % che permette di fare “format
 string” simili alla printf del C. -- man printf --
  stringa % tupla: sostituzione posizionale:
 >>> '%s %d %s' % ('ciao', 9, ('h', 'p'))
 "ciao 9 ('h', 'p')"

  stringa % dizionario: sostituzione                  per nome:
 >>> 'Mi chiamo %(surname)s, %(fname)s %(surname)s.' % {'surname': 'Bond', 'fname' : 'James'}
 'Mi chiamo Bond, James Bond.'

 Estremamente comodo. Usando %s si passa per str(obj), usando
 %r per repr(obj)
Esempio dizionari                                     30

   import sys
   filename = sys.argv[1]

   indx = {}
   try:
       f = open(filename)
        for n, line in enumerate(f):
            for word in line.split():
                indx.setdefault(word, []).append(n)
   finally:
       f.close()

   for word in sorted(indx): # indice alfabetico
       print "%s:" % word,
       for n in indx[word]: print n,
       print
I/O elementare                                                             31

 due funzioni built-in per l'input elementare
   input(prompt): immette     qualsiasi espressione -- ne torna il valore
   raw_input(prompt): torna     una stringa, rimuove il n a fine stringa
 un’istruzione per l'output elementare
   print <0+ espressioni separate da virgole>

   separa i risultati con uno spazio
   n alla fine (ma non se terminate con virgola)
   print   di suo non fa formattazioni speciali
   print >> writable, <0+ espressioni separate da virgole>
Eccezioni                                          32

 Errori (e “anomalie” che non sono errori)
 “sollevano eccezioni”
 L’istruzione raise solleva un’eccezione
 Le eccezioni si propagano “lungo lo stack delle
 chiamate”, man mano terminando le funzioni,
 sinchè non vengono “catturate”
 Se non catturate, terminano il programma
 L'istruzione try/except può catturare eccezioni
 (anche: try/finally, e l'elegante with per
 implementare “RAII”)
LBYL vs. EAFP                                                  33

LBYL: Look before you leap        # LBYL -- cattivo
                                  if user_name in employees:
EAFP: Easier to ask forgiveness       emp =
than permission                   employees[user_name]
                                  else:
Normalmente EAFP è la                 report_error(...)
strategia migliore in Python
  Eccezioni relativamente poco
  costose                         #EAFP -- buono
                                  try:
  Atomicità, ...                      emp =
                                  employees[user_name]
                                  except KeyError:
                                      report_error(...)
Vari tipi di try                                          34
try:
    # codice che potrebbe lanciare eccezione
except IndexError, exc:
    # un tipo di errore
    # opzionalmente si mette ‘, nome’ per avere
    # l’oggetto eccezione da gestire
except AnotherException:
    # gestione di un altro errore
except:
    # gestione di ogni eccezione
    # tipicamente *NON* e' una buona pratica
    # a meno di non rilanciare
    raise   # raise vuoto rilancia l'eccezione corrente
finally:
    # questo codice e' eseguito *sempre*
    # codice di pulizia sia con errore che senza
List Comprehensions                                       35

“Matematichese”:     { f (x) | ∀x ∈S tali che p(x)}
Python:
   [f(x) for x in seq if p(x)]

   Lista di tutti gli f(x) per tutti gli x contenuti in
  seq, a patto che p(x) sia vero.

Simile a:
 tmp = []
 for x in seq:
     if p(x):
         tmp.append(f(x))
Generator Expressions                                36

 Si può fare restituendo un generatore, ovvero un
 iterabile “lazy”
 Il calcolo avviene solo mano a mano che i nuovi
 elementi sono “richiesti”
 Sintassi:   (f(x) for x in seq if p(x))


 Comodo con altre funzioni
 sum(f(x) for x in seq if p(x))
 set(f(x) for x in seq if p(x))
 dict((x, i) for (i, x) in enumerate(sorted(seq)))
Funzioni                                                    37

 def <nome>(<parametri>): <corpo>

   <corpo>   compilato, ma non subito eseguito
   <parametri>: 0+ variabili locali, inizializzate   alla
  chiamata dagli <args> passati
  gli 0+ ultimi parameters possono avere "valori di
  default", <nome>=<expr> (expr è valutata una sola
  volta, quando def esegue)
   <parametri>    può finire con *<nome> (tupla di
  arbitrari arg posizionali) e/o **<nome> (dict di
  arbitrari arg con nome)
Esempio:
somma di quadrati                              38
def sumsq(a, b):
    return a*a+b*b
print sumsq(23, 45) # => 2554

O, piú generale:
def sumsq(*a):
    return sum(x*x for x in a)
print sumsq(23, 45) # => 2554
print sumsq(23, 45, 44, 2) # => 4494

Minore livello di astrazione, + lento ma OK:
def sumsq(*a):
    total = 0
    for x in a:
        total += x*x
    return total
“semplice wget” (GvR)                         39


      import sys
      import urllib
      import os


      def hook(*a):
          print '%s: %s' % (fn, a)

      for url in sys.argv[1:]:
          fn = os.path.basename(url)
          print url, "->", fn
          urllib.urlretrieve(url, fn, hook)
Classi                                                                    40

                                    class Stack(object):
 Classe Stack, eredita da               def __init__(self, seq):
 object (come tutto)                        self._els = list(seq)

 Costruttore __init__, ha per             def pop(self):
                                              return self._els.pop()
 parametro qualcosa di
 convertibile in lista                    def push(self, el):
                                              return self._els.append(el)
 Metodo pop delega al pop                 def __len__(self):
 della lista                                  return len(self._els)
                                    >>>   import stack
 Push “delega”   all’append della   >>>   s = stack.Stack([1, 4, 7, 8])
 lista                              >>>   s.pop()
                                    8
 __len__, numero    di elementi     >>>   s.push(3)
                                    >>>   s.pop()
                                    3
Con documentazione                                    41

class Stack(object):
    'Implements a stack'
    def __init__(self, seq):
        'Create a new stack with elements from seq'
        self._elements = list(seq)

    def pop(self):
        'Remove and return the head of the stack'
        return self._elements.pop()

    def push(self, element):
        'Add el to the head of the stack'
        return self._elements.append(element)

    def __len__(self):
        return len(self._elements)
class Duration(object):
    def __init__(self, minutes=0, seconds=0):
        if minutes < 0 or seconds < 0:
            raise ValueError("Duration times should be positive")
        self._duration = minutes * 60 + seconds             42
    def minutes(self):
        return self._duration / 60

    def seconds(self):
        return self._duration % 60

    def __str__(self):
        return '%d:%02d' % (self.minutes(), self.seconds())

d1 = Duration(minutes=3)
d2 = Duration(seconds=6)
d3 = Duration(minutes=4, seconds=3)

print d1.minutes(), d1.seconds() # => 3 0
print d1, d2, d3 # => 3:00 0:06 4:03
Operatori                                                        43

In Python sono disponibili operatori per i tipi
definiti dall’utente (== C++, != Java)
                             Python                  C++
   uguale/diverso            __eq__               operator==
     addizione              __add__                operator+
       minore                __lt__                operator<
         []              __(g|s)etitem__           operator[]
   chiamata funz.           __call__               operator()
        hash               __hash__                    ...
    conversioni             __int__               operator int
         ...                    ...                    ...
class Duration(object):

    ...

    def __add__(self, other):
                                                     44
        return Duration(seconds=self._duration + 
                        other._duration)


class Track(object):
    def __init__(self, artist, title, duration):
        self.artist = artist
        self.title = title
        self.duration = duration

    def __str__(self):
        return '%s - %s - %s' % (self.artist,
                                 self.title,
                                 self.duration)
class MusicRecord(object):
    def __init__(self, title, tracks):
        self.title = title
        if not tracks:
            raise ValueError("Empty track list.")
        self.tracks = tuple(tracks)                            45

    def is_compilation(self):
        artists = set(track.artist for track in self.tracks)
        return len(titles) > 1

    def get_duration(self):
        return sum((track.duration for track in self.tracks),
                   Duration())

    def get_artist(self):
        if self.is_compilation():
            return 'AA. VV.'
        else:
            return self.tracks[0].title

    def get_title(self):
        return self.title
lz = 'Led Zeppelin'
tracks = [
    Track(lz, 'Whole Lotta Love', Duration(5, 34)),
    Track(lz, 'What Is and What Should Never Be',          46
          Duration(4, 44)),
    Track(lz, 'The Lemon Song', Duration(6, 19)),
    Track(lz, 'Thank You', Duration(4, 47)),
    Track(lz, 'Heartbreaker', Duration(4, 14)),
    Track(lz, "Living Loving Maid (She's Just a Woman)",
          Duration(2, 39)),
    Track(lz, 'Ramble On', Duration(4, 23)),
    Track(lz, 'Moby Dick', Duration(4, 21)),
    Track(lz, 'Bring It On Home', Duration(4, 20))
]

lz2 = MusicRecord('Led Zeppelin II', tracks)
print lz2.get_duration() # => 41:21
Properties (I)                                                           47

                                  class A(object):
 Abbiamo scelto di usare per          def __init__(self, foo):
 Track attributi pubblici                 self._foo = foo

                                      def get_foo(self):
 Supponiamo di volere                     print 'got foo'
                                          return self._foo
 aggiungere controlli, per
 esempio validare gli                 def set_foo(self, val):
                                          print 'set foo'
 assegnamenti, oppure                     self._foo = val

 renderli impossibili...              foo = property(get_foo, set_foo)
 bisognerebbe modificare il        a = A('ciao')
 codice?                          print a.foo
                                  # => 'got foo'
 property: sintassi
                  di attributi,   # => 'ciao'
                                  a.foo = 'bar'
 sotto chiama funzioni            # => 'set foo'
Properties (II)                                           48

 E se non vogliamo il setter del tutto? Non mettiamolo!
 class A(object):
     def __init__(self, foo):
         self._foo = foo

     def get_foo(self):
         print 'got foo'
         return self._foo

    foo = property(get_foo)

 a = A('ciao')
 print a.foo
 # => 'got foo'
 # => 'ciao'
 a.foo = 'bar'
 # Traceback (most recent call last):
 # File "prop_example2.py", line 15, in <module>
 #    a.foo = 'bar'
 # AttributeError: can't set attribute'
Properties (III)                                       49

 Snelliamo la sintassi. Possiamo usare un decoratore
 class A(object):
     def __init__(self, foo):
         self._foo = foo

     @property
     def foo(self):
         print 'got foo'
         return self._foo


 a = A('ciao')
 print a.foo
 # => 'got foo'
 # => 'ciao'
 a.foo = 'bar'
 # Traceback (most recent call last):
 # File "prop_example2.py", line 15, in <module>
 #    a.foo = 'bar'
 # AttributeError: can't set attribute'
Properties (IV)                      50

 Con Python 2.6, anche con setter:
 class A(object):
     def __init__(self, foo):
         self._foo = foo

     @property
     def foo(self):
         print 'got foo'
         return self._foo

     @foo.setter
     def foo(self, value):
         print 'set foo'
         self._foo = value


 a = A('ciao')
 a.foo = 'bar'
 # => 'set foo'
class Track(object):
    def __init__(self, artist, title, duration):
        self._artist = artist
        self._title = title
        self._duration = duration                  51
    @property
    def artist(self):
        return self._artist

    @property
    def title(self):
        return self._title

    @property
    def duration(self):
        return self._duration

    def __str__(self):
        return '%s - %s - %s' % (self.artist,
                                 self.title,
                                 self.duration)
class MusicRecord(object):
    def __init__(self, title, tracks):
        self.title = title
        if not tracks:
            raise ValueError("Empty track list.")           52
        self.tracks = tuple(tracks)
        self._artists = set(track.artist for track in self.tracks)
        self._duration = sum((track.duration for track
                              in self.tracks), Duration())

    @property
    def is_compilation(self):
        return len(self._titles) > 1

    @property
    def duration(self):
        return self._duration

    @property
    def artist(self):
        if self.is_compilation:
            return 'AA. VV.'
        else:
            return self.tracks[0].title
Adulti e vaccinati...                                              53

 Possiamo impedire l’accesso usando le properties
 Possiamo usare meta-programmazione1 per
 scrivere meno codice
 Es... namedtuple, definita nella libreria standard
 Track = collections.namedtuple(
   'Track', ['title', 'artist', 'duration'])




   1. meta-programmazione: scrittura di programmi che scrivono
      o modificano altri programmi (o se stessi) come i loro dati
Decoratori (I)                                                       54

                                 def log(f):
 Un decoratore nella sua             def _aux(*args, **kargs):
 generalità è una funzione che           print 'Called %s' % f.__name__
                                         return f(*args, **kargs)
 accetta una funzione come           return _aux

 parametro e ne restituisce      @log
                                 def double(n):
 una versione modificata               return 2 * n

  @deco                          class eg(object):
  def f(...): ...                    @log
                                     def foo(self):
 equivale a:                              print 'foo'

  def f(...): ...                double(10) # => Called double
                                 eg().foo()
  f = deco(f)                    # => Called foo
                                 # => foo
Decoratori (II)                                                         55

 Esempio da Django (web framework)
 from django.contrib.auth.decorators import login_required

 @login_required
 def my_view(request):
     ...

 Un decoratore può anche avere argomenti
 I decoratori si possono combinare
 class Bank(object):
     # ...
     @with_logger(default_logger)
     @atomic
     def transfer(self, from_, to, amount):
         self.accounts[from_] -= amount # raises NegativeAccountError
         self.accounts[to] += amount
Dinamismo e
introspezione                                     56

 Quando un attributo di un oggetto non viene
 trovato, se è definito il metodo __getattr__
   Se si, viene chiamato con come parametro il
   nome dell’attributo cercato
 Esempio: delega [prossima slide]
 Funzione getattr: prende un attributo per nome
   f.foo
 
getattr(f,
‘foo’)
Stack (con delega)                                        57
  class Stack(object):
      delegates = dict(pop='pop', push='append')

      def __init__(self, seq):
          self._elements = list(seq)

      def __getattr__(self, value):
          try:
              delegate_name = Stack.delegates[value]
          except KeyError:
               raise AttributeError
          else:
              delegate_method = getattr(self._elements,
                                        delegate_name)
               return delegate_method
Convenzioni (PEP8)                                  58




     http://www.python.it/doc/articoli/pep-8.html
Importare Moduli                                          59

import nomemodulo
from un.certo.package import nomemodulo

  poi si usa nomemodulo.foo
  ci sono abbreviazioni (non necessariamente buone...):
    accorciare i nomi con la clausola as:
    import itertools as it
       poi si usa it.izip
    from itertools import izip
    from itertools import *
Esempio di Import                                  60

import math
print math.atan2(1, 3)
# emette 0.321750554397
print atan2(1, 3)
# solleva un'eccezione NameError

from math import atan2

 inietta atan2 nel namespace corrente
 comodo in interattivo, ma spesso illeggibile in
 “veri” programmi: evitare!
 peggio ancora (evitare COME LA PESTE!):
    from math import *
Definire Moduli                                           61

ogni sorgente Python wot.py è un modulo
basta fare import wot
  deve vivere nella path d'importazione
  ...che è la lista path nel modulo sys, ogni elemento
  una stringa che nomina un dir (o zipfile, ...)
  contenente moduli Python
  pure importabili: file di bytecode (wot.pyc),
  automaticamente creati dal compilatore Python
  quando importi un .py
  pure importabili: estensioni binarie (wot.pyd),
  scritte in C (or pyrex, SWIG, ...)
Persistenza                                              62

 cPickle: tutti gli oggetti sono facilmente e
 automaticamente serializzabili su disco
 Modulo shelve
   Si usa come un dizionario, offre gratis persistenza
   su disco per strutture chiave-valore
   Esigenze maggiori? SQLite integrato con Python
   Non basta? PostgreSQL
      Scriptabile in Python
      Accessibile da Python (+ ORM, SQLAlchemy)
Rete                                              63

Modulo socket, offre socket C-like (ma più
semplici da usare)
Moduli asyncore: programmazione asincrona
semplice
Moduli poplib, urllib, smtplib, email, imaplib
Moduli serverside: TCPServer, TCPForkingServer,
TCPThreadingServer, UDP...
Twisted (asyncrono, altissima efficienza)
Tornado (facebook)
Interfacce grafiche                                    64

 Tkinter
   Multipiattaforma, libreria standard, bruttarello
 Qt
   Piattaforma ricchissima, cross-platform, ++
 wx
   Cross-platform, ... [non inneschiamo flames]
 GTK, Cocoa, WinAPI, + .Net con IronPython,
 Swing con Jython, FLTK...
Calcolo scientifico                            65

 PIL
   Manipolazione immagini
 Numpy+Matplotlib
   Calcolo numerico, simile a Matlab/Octave
 Scipy
   Ulteriori librerie
 http://www.scipy.org/
Web                                                66

cgi (sconsigliato)/fastcgi
WSGI: modulo di medio livello per interfacciarsi
con i server
Django: framework completo, molto usato
Nevow: framework completo basato su Twisted
Zope2/3: “mega framework”
Google App Engine (+web.py ev. Django)
web.py: modulo minimalista, facile comprensione
Q&A
Help System               Ancora su Classi e Istanze
                                                       67




                               Generatori &
Attributi di Classe
                              Generatori Infiniti
                      Scope
 With Statement
                                 Duck Typing
Help system                                                                    68
                                 >>> help(os.getcwd)
La funzione help() da aiuto su   getcwd(...)
                                   getcwd() -> path
una funzione/classe/modulo
                                   Return a string representing the current working direc
etc.                             >>> help(sys)
                                 Help on built-in module sys:
Se chiamata sull’istanza di
                                 NAME
una classe (quindi anche un        sys
numero o una stringa) da         FILE
informazioni sulla classe           (built-in)

Di fatto va a leggere le         MODULE DOCS
                                   http://www.python.org/doc/current/lib/module-sys.h
‘docstring’ (vediamo poi...)
                                 DESCRIPTION
                                   This module provides access to some objects used or
Consideriamo anche pydoc           interpreter and to functions that interact strongly with
Help system                                                                   68
>>> help(os.getcwd)
getcwd(...)
  getcwd() -> path

  Return a string representing the current working directory.
>>> help(sys)
Help on built-in module sys:

NAME
  sys

FILE
   (built-in)

MODULE DOCS
  http://www.python.org/doc/current/lib/module-sys.html

DESCRIPTION
  This module provides access to some objects used or maintained by the
  interpreter and to functions that interact strongly with the interpreter.
>>> help(sys.stdout)
Help on file object:

class file(object)
 | file(name[, mode[, buffering]]) -> file object
 |
 | Open a file. The mode can be 'r', 'w' or 'a' for reading (default),
 | writing or appending. The file will be created if it doesn't exist             69
 | when opened for writing or appending; it will be truncated when
 | opened for writing. Add a 'b' to the mode for binary files.
                                 ...
bash> pydoc os.path.join
Help on function join in os.path:

os.path.join = join(a, *p)
  Join two or more pathname components, inserting '/' as needed


bash> pydoc -p 8080
pydoc server ready at http://localhost:8080/


% python
>>> help()

Welcome to Python 2.5! This is the online help utility.

help>
                                                                        To Q&A
>>> help(sys.stdout)
Help on file object:

class file(object)
 | file(name[, mode[, buffering]]) -> file object
 |
 | Open a file. The mode can be 'r', 'w' or 'a' for reading (default),
 | writing or appending. The file will be created if it doesn't exist             69
 | when opened for writing or appending; it will be truncated when
 | opened for writing. Add a 'b' to the mode for binary files.
                                 ...
bash> pydoc os.path.join
Help on function join in os.path:

os.path.join = join(a, *p)
  Join two or more pathname components, inserting '/' as needed


bash> pydoc -p 8080
pydoc server ready at http://localhost:8080/


% python
>>> help()

Welcome to Python 2.5! This is the online help utility.

help>
                                                                        To Q&A
Attributi
di istanza e di classe                                             70

                                  class A(object):
 Fino ad ora abbiamo visto            cattr = []
                                      def __init__(self):
 come aggiungere attributi alle           self.iattr = []
 istanze delle classi (banale)        def add(self, obj):
                                          self.cattr.append(obj)
 Sappiamo che le funzioni, in             self.iattr.append(obj)
 un certo senso sono attributi    a1 = A()
 degli “oggetti classe”           a2 = A()
                                  a1.add('x')
                                  print a1.cattr, a1.iattr
 Se definiamo un attributo nel     # => ['x'], ['x']
 corpo di una classe, è un        print a2.cattr, a2.iattr
                                  # => ['x'], []
 attributo di classe              a2.add('y')
                                  print a1.cattr, a1.iattr
                                  # => ['x', 'y'], ['x']
                                  print a2.cattr, a2.iattr
                                  # => ['x', 'y'], ['y']
Metodi di classe                                              71

 I metodi di classe si          class A(object):
                                    @classmethod
 definiscono con il decoratore       def say(cls, m):
 classmethod
                                        print cls.__name__, m
 Hanno come primo
                                A.say('hello') # => A hello
 argomento l’oggetto classe     a = A()
   Accedono ad attributi di     a.say('hello') # => A hello
   classe (ma non d’istanza)
 Convenzionalmente,
 chiamiamo il primo
 parametro cls e non self
                                                    To Q&A
With statement                                     72

                with file('foo.txt') as f:
                    for line in f:
                        print line.strip()



 with gestisce un “contesto”, quando si esce dal
blocco with (con eccezione o meno), viene
gestita la chiusura di file
Simile agli idiomi RAII (resource allocation is
initialization) di C++, ma molto più facile da
gestire
Vecchio esempio...                                      73

 import sys
 filename = sys.argv[1]

 indx = {}

 with open(filename) as f:
     for n, line in enumerate(f):
         for word in line.split():
             indx.setdefault(word, []).append(n)

 # mostriamola in indice alfabetico
 for word in sorted(indx):
     print "%s:" % word,
     for n in indx[word]: print n,
     print                                         To Q&A
Generatori                                                     74

                                  def couples(l):
funzioni con yield invece di          i = 0
return                                length = len(l)
                                      while i < length-1:
ogni chiamata costruisce e                yield l[i], l[i+1]
torna un iteratore (oggetto               i += 1
con metodo next, adatto a
                                  lst = [1, 2, 3, 4, 5, 6]
essere iterato in un ciclo for)   for pairs in couples(lst):
la fine della funzione solleva         print pairs
StopIteration                     (1,   2)
                                  (2,   3)
                                  (3,   4)
                                  (4,   5)
                                  (5,   6)
Generatori Infiniti                         75

      def fibonacci():
          i = j = 1
          while True:
              r, i, j = i, j, i + j
              yield r

      for rabbits in fibonacci():
          if rabbits > 100:
              break
          else:
              print rabbits,



     1 1 2 3 5 8 13 21 34 55 89
                                      To Q&A
Classi                                                76

class <nome>(<basi>):
  <corpo>


 <corpo> è di solito una serie di istruzioni def e
 assegnazioni; i nomi definiti o assegnati divengono
 attributi del nuovo oggetto classe <nome> (le
 funzioni divengono "metodi")
 gli attributi di una qualsiasi base sono anche
 attributi della nuova classe, se non
 "overridden" (assegnati o definiti nel corpo)
 Iniziare con singolo _ indica essere privati
Istanziare una Classe                              77


class eg(object):
  cla = []                 #   attrib. di classe
  def __init__(self):      #   inizializzatore
    self.ins = {}          #   attrib. d'istanza
  def meth1(self, x):      #   un metodo
    self.cla.append(x)
  def meth2(self, y, z):   # altro metodo
    self.ins[y] = z

es1 = eg()
es2 = eg()
Classi e Istanze                           78

print es1.cla, es2.cla, es1.ins, es2.ins
[] [] {} {}

es1.meth1(1); es1.meth2(2, 3)
es2.meth1(4); es2.meth2(5, 6)

print es1.cla, es2.cla, es1.ins, es2.ins
[1, 4] [1, 4] {2: 3} {5: 6}

print es1.cla is es2.cla
True
print es1.ins is es2.ins
False
Risoluzione degli Attributi                       79

inst.method(arg1, arg2)

type(inst).method(inst, arg1, arg2)
inst.nome [[che sia poi chiamato o meno!]]
    (i "descrittori" possono alterarlo...)
 prova inst.__dict__['nome']
 prova type(inst).__dict__['nome']
 prova ciascuna delle type(inst).__bases__
 prova type(inst).__getattr__(inst, 'nome')
 se tutto fallisce, raise AttributeError      To Q&A
Scope delle variabili                                      80

 I parametri di una funzione e ogni variabile che
 viene legata (con assegnamento o statement
 come def o class) nel corpo di una funzione
 costituisce il namespace della funzione (local
 scope)
 Lo scope di queste variabili è tutto il corpo della
 funzione (ma usarle prima che siano state legate
 è un errore)
 Le variabili non locali sono dette globali, il loro
 scope è il modulo intero
   Normalmente non ci sono motivi per usarle           To Q&A
Scope delle variabili                                      80

 I parametri di una funzione e ogni variabile che
 viene legata (con assegnamento o statement
 come def o class) nel corpo di una funzione
 costituisce il namespace None funzione (local
                            della
                       a=
 scope)               if s.startswith(t):
                        a = s[:4]
 Lo scope di queste variabili è tutto il corpo della
                     else:
 funzione (ma usarle prima tche siano state legate
                        a=
 è un errore)        print a
 Le variabili non locali sono dette globali, il loro
                            SBAGLIATO
 scope è il modulo intero
   Normalmente non ci sono motivi per usarle           To Q&A
Scope delle variabili                                      80

 I parametri di una funzione e ogni variabile che
 viene legata (con assegnamento o statement
 come def o class) nel corpo di una funzione
 costituisce il namespace della funzione (local
 scope)               if s.startswith(t):
                        a = s[:4]
 Lo scope di queste variabili è tutto il corpo della
                     else:
 funzione (ma usarle prima tche siano state legate
                        a=
 è un errore)        print a
 Le variabili non locali sono dette globali, il loro
                              GIUSTO
 scope è il modulo intero
   Normalmente non ci sono motivi per usarle           To Q&A
Pensiamo a Java/C++...                             81

 Nei linguaggi con un type-system derivato da C+
 + chiediamo che i parametri di una certa
 funzione abbiano un dato tipo (o siano di un
 sottotipo)
 Questo è poco flessibile: programmare per un
 interfaccia
   Interfacce di Java (vero polimorfismo din.)
   Templates di C++ (polimorfismo statico)
   Sono soluzioni con problemi
Libri, ricerca per titolo                                               82

Chiamare su una lista che   class Book(object):
                                def __init__(self, title, author):
contiene un “non libro”             self.title = title
                                    self.author = author
lancia eccezione
                            def find_by_title(seq, title):
Eppure non gestiamo             for item in seq:
                                    if type(item) == Book: # horrible
nemmeno sottoclassi                     if item.title == title:
                                            return item
Peggior codice possibile,           else:
                                        raise TypeError
inoltre stiamo risolvendo
                            def find_by_author(seq, author):
un non-problema                 for item in seq:
                                    if type(item) == Book: # horrible
                                        if item.author == author:
                                            return item
                                    else:
                                        raise TypeError
Libri, ricerca per titolo   82

Chiamare su una lista che
contiene un “non libro”
lancia eccezione
Eppure non gestiamo
nemmeno sottoclassi
Peggior codice possibile,
inoltre stiamo risolvendo
un non-problema
Libri, ricerca per titolo                                                83

Ora gestiamo sottoclassi      class Book(object):
                                  def __init__(self, title, author):
                                      self.title = title
Eppure noi non usiamo mai             self.author = author
il fatto che la cosa sia un   def find_by_title(seq, title):
libro                             for item in seq:
                                      if isinstance(item, Book): # bad
                                          if item.title == title:
  Solo che ha un titolo                       return item
                                      else:
  Solo che ha un autore                   raise TypeError

Cosa succede se abbiamo       def find_by_author(seq, author):
                                  for item in seq:
una classe Song?                      if isinstance(item, Book): # bad
                                          if item.author == author:
                                              return item
                                      else:
                                          raise TypeError
Libri, ricerca per titolo                                                83

Ora gestiamo sottoclassi
Eppure noi non usiamo mai
il fatto che la cosa sia un   def find_by_title(seq, title):
libro                             for item in seq:
                                      if isinstance(item, Book): # bad
                                          if item.title == title:
  Solo che ha un titolo                       return item
                                      else:
  Solo che ha un autore                   raise TypeError

Cosa succede se abbiamo       def find_by_author(seq, author):
                                  for item in seq:
una classe Song?                      if isinstance(item, Book): # bad
                                          if item.author == author:
                                              return item
                                      else:
                                          raise TypeError
Libri, ricerca per titolo                                                83

Ora gestiamo sottoclassi      class Song(object):
                                  def __init__(self, title, author):
                                      self.title = title
Eppure noi non usiamo mai             self.author = author
il fatto che la cosa sia un   def find_by_title(seq, title):
libro                             for item in seq:
                                      if isinstance(item, Book): # bad
                                          if item.title == title:
  Solo che ha un titolo                       return item
                                      else:
  Solo che ha un autore                   raise TypeError

Cosa succede se abbiamo       def find_by_author(seq, author):
                                  for item in seq:
una classe Song?                      if isinstance(item, Book): # bad
                                          if item.author == author:
                                              return item
                                      else:
                                          raise TypeError
Libri e canzoni                                                     84

                                    La cosa più semplice è la migliore
class Book(object):                 I programmatori tendono a non
    def __init__(self, t, a):
        self.title = t
                                    scrivere codice a caso
        self.author = a
                                    Abbiamo sempre eccezioni
def find_by_title(seq, title):
    for item in seq:
                                    lanciate
        if item.title == title:
            return item             I test servono apposta per
def find_by_author(seq, author):    prendere ‘sta roba
    for item in seq:
        if item.author == author:
            return item
E se avessimo film?                                85

 I film hanno sempre un titolo, ma non hanno un
 autore, bensì un regista
 find_by_title dovrebbe   funzionare,
 find_by_author, no

 Interfaccia per Book e Song. E per Movie?
 Design Pattern o duplicazione di codice
 Ruota quadrata    strade per ruote quadrate

 Con il duck typing non dobbiamo cambiare nulla
def find_by(seq, **kwargs):
    for obj in seq:                              To Q&A
        for key, val in kwargs.iteritems():
            try:
                 if getattr(obj, key) != val:
                     break
            except KeyError:
                 break
        else:
            return obj
    raise NotFound

print find_by(books, title='Python in a Nutshell')
print find_by(books, author='M. Beri')
print find_by(books, title='Python in a Nutshell',
                     author='A. Martelli')

try:
    print find_by(books, title='Python in a Nutshell',
                         author='M.Beri')
    print find_by(books, title='Python in a Nutshell',
                         pages=123)
except NotFound: pass

Weitere ähnliche Inhalte

Was ist angesagt?

Pycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjamPycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjamrik0
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java BaseK-Tech Formazione
 
Multithreading, multiprocessing e Asincronia
Multithreading, multiprocessing e AsincroniaMultithreading, multiprocessing e Asincronia
Multithreading, multiprocessing e AsincroniaSebastiano Merlino (eTr)
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsJUG Genova
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewFrancesco Sciuti
 
Gestione della memoria in C++
Gestione della memoria in C++Gestione della memoria in C++
Gestione della memoria in C++Ilio Catallo
 
Acadevmy - ES6 Modern JS Today
Acadevmy - ES6 Modern JS TodayAcadevmy - ES6 Modern JS Today
Acadevmy - ES6 Modern JS TodayFrancesco Sciuti
 
2011.02.19 Introducing F#
2011.02.19 Introducing F#2011.02.19 Introducing F#
2011.02.19 Introducing F#Marco Parenzan
 
12 - Programmazione: Array dinamici e puntatori
12 - Programmazione: Array dinamici e puntatori12 - Programmazione: Array dinamici e puntatori
12 - Programmazione: Array dinamici e puntatoriMajong DevJfu
 
Let's give it a GO!
Let's give it a GO!Let's give it a GO!
Let's give it a GO!MarioTraetta
 
Py a6 python-database
Py a6 python-databasePy a6 python-database
Py a6 python-databaseMajong DevJfu
 
14 - Programmazione: Stream e File
14 - Programmazione: Stream e File14 - Programmazione: Stream e File
14 - Programmazione: Stream e FileMajong DevJfu
 
Py a3 python-metaprogramming
Py a3 python-metaprogrammingPy a3 python-metaprogramming
Py a3 python-metaprogrammingMajong DevJfu
 
Py a2 python-documentazione
Py a2 python-documentazionePy a2 python-documentazione
Py a2 python-documentazioneMajong DevJfu
 

Was ist angesagt? (20)

Bash programming
Bash programmingBash programming
Bash programming
 
Pycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjamPycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjam
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
Rest sdk
Rest sdkRest sdk
Rest sdk
 
Multithreading, multiprocessing e Asincronia
Multithreading, multiprocessing e AsincroniaMultithreading, multiprocessing e Asincronia
Multithreading, multiprocessing e Asincronia
 
2006 Py04 avanzato
2006 Py04 avanzato2006 Py04 avanzato
2006 Py04 avanzato
 
Corso c++
Corso c++Corso c++
Corso c++
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMs
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript Overview
 
Gestione della memoria in C++
Gestione della memoria in C++Gestione della memoria in C++
Gestione della memoria in C++
 
Pillole di C++
Pillole di C++Pillole di C++
Pillole di C++
 
Acadevmy - ES6 Modern JS Today
Acadevmy - ES6 Modern JS TodayAcadevmy - ES6 Modern JS Today
Acadevmy - ES6 Modern JS Today
 
2011.02.19 Introducing F#
2011.02.19 Introducing F#2011.02.19 Introducing F#
2011.02.19 Introducing F#
 
12 - Programmazione: Array dinamici e puntatori
12 - Programmazione: Array dinamici e puntatori12 - Programmazione: Array dinamici e puntatori
12 - Programmazione: Array dinamici e puntatori
 
Let's give it a GO!
Let's give it a GO!Let's give it a GO!
Let's give it a GO!
 
Py a6 python-database
Py a6 python-databasePy a6 python-database
Py a6 python-database
 
Py t1 python-intro
Py t1 python-introPy t1 python-intro
Py t1 python-intro
 
14 - Programmazione: Stream e File
14 - Programmazione: Stream e File14 - Programmazione: Stream e File
14 - Programmazione: Stream e File
 
Py a3 python-metaprogramming
Py a3 python-metaprogrammingPy a3 python-metaprogramming
Py a3 python-metaprogramming
 
Py a2 python-documentazione
Py a2 python-documentazionePy a2 python-documentazione
Py a2 python-documentazione
 

Andere mochten auch

Audubom International Certification
Audubom International CertificationAudubom International Certification
Audubom International CertificationAlys Spillman
 
Social Entrepreneurship
Social EntrepreneurshipSocial Entrepreneurship
Social EntrepreneurshipDax Basdeo
 
Top Ten Slide Tips
Top Ten Slide TipsTop Ten Slide Tips
Top Ten Slide Tips大璋 王
 
牛市赚钱并不容易
牛市赚钱并不容易牛市赚钱并不容易
牛市赚钱并不容易大璋 王
 
好生意专业店铺服务在阿里软件、淘宝开放平台的1年
好生意专业店铺服务在阿里软件、淘宝开放平台的1年好生意专业店铺服务在阿里软件、淘宝开放平台的1年
好生意专业店铺服务在阿里软件、淘宝开放平台的1年jay zhou
 
PROPRICER Presentation
PROPRICER PresentationPROPRICER Presentation
PROPRICER PresentationPROPRICER
 
Change or Die ANA Magazine - Marketing2020 story
Change or Die ANA Magazine - Marketing2020 storyChange or Die ANA Magazine - Marketing2020 story
Change or Die ANA Magazine - Marketing2020 storyVermeer
 
Using Wikis + Blogs In Business
Using Wikis + Blogs In BusinessUsing Wikis + Blogs In Business
Using Wikis + Blogs In BusinessDax Basdeo
 
Cursus Enterprise Output Management Solutions (EOMS)
Cursus Enterprise Output Management Solutions (EOMS)Cursus Enterprise Output Management Solutions (EOMS)
Cursus Enterprise Output Management Solutions (EOMS)Johan Kosters
 
网络定向广告推广与精准营销
网络定向广告推广与精准营销网络定向广告推广与精准营销
网络定向广告推广与精准营销大璋 王
 
1.巴菲特成功全赖特许经营权
1.巴菲特成功全赖特许经营权1.巴菲特成功全赖特许经营权
1.巴菲特成功全赖特许经营权大璋 王
 
Witt Limited Business Plan
Witt Limited Business PlanWitt Limited Business Plan
Witt Limited Business PlanPeter Beech
 
Global Issues Project
Global Issues ProjectGlobal Issues Project
Global Issues Projecttechray3
 
replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013
replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013
replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013webwinkelvakdag
 
Mohamed Alaaeldin Farouk-CV
Mohamed Alaaeldin  Farouk-CVMohamed Alaaeldin  Farouk-CV
Mohamed Alaaeldin Farouk-CVMohamed Aladdin
 
Level 1 Programme_IWCF Level 1 Programme
Level 1 Programme_IWCF Level 1 ProgrammeLevel 1 Programme_IWCF Level 1 Programme
Level 1 Programme_IWCF Level 1 ProgrammeABDUL MANAN BHAYO
 

Andere mochten auch (20)

Audubom International Certification
Audubom International CertificationAudubom International Certification
Audubom International Certification
 
Social Entrepreneurship
Social EntrepreneurshipSocial Entrepreneurship
Social Entrepreneurship
 
Parigi
ParigiParigi
Parigi
 
Top Ten Slide Tips
Top Ten Slide TipsTop Ten Slide Tips
Top Ten Slide Tips
 
Matemáticas
MatemáticasMatemáticas
Matemáticas
 
牛市赚钱并不容易
牛市赚钱并不容易牛市赚钱并不容易
牛市赚钱并不容易
 
好生意专业店铺服务在阿里软件、淘宝开放平台的1年
好生意专业店铺服务在阿里软件、淘宝开放平台的1年好生意专业店铺服务在阿里软件、淘宝开放平台的1年
好生意专业店铺服务在阿里软件、淘宝开放平台的1年
 
Bay C Mod Floor
Bay C Mod FloorBay C Mod Floor
Bay C Mod Floor
 
Graphene Frontiers
Graphene FrontiersGraphene Frontiers
Graphene Frontiers
 
PROPRICER Presentation
PROPRICER PresentationPROPRICER Presentation
PROPRICER Presentation
 
Change or Die ANA Magazine - Marketing2020 story
Change or Die ANA Magazine - Marketing2020 storyChange or Die ANA Magazine - Marketing2020 story
Change or Die ANA Magazine - Marketing2020 story
 
Using Wikis + Blogs In Business
Using Wikis + Blogs In BusinessUsing Wikis + Blogs In Business
Using Wikis + Blogs In Business
 
Cursus Enterprise Output Management Solutions (EOMS)
Cursus Enterprise Output Management Solutions (EOMS)Cursus Enterprise Output Management Solutions (EOMS)
Cursus Enterprise Output Management Solutions (EOMS)
 
网络定向广告推广与精准营销
网络定向广告推广与精准营销网络定向广告推广与精准营销
网络定向广告推广与精准营销
 
1.巴菲特成功全赖特许经营权
1.巴菲特成功全赖特许经营权1.巴菲特成功全赖特许经营权
1.巴菲特成功全赖特许经营权
 
Witt Limited Business Plan
Witt Limited Business PlanWitt Limited Business Plan
Witt Limited Business Plan
 
Global Issues Project
Global Issues ProjectGlobal Issues Project
Global Issues Project
 
replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013
replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013
replatforming eCommerce – Bijenkorf case - Webwinkel Vakdagen 2013
 
Mohamed Alaaeldin Farouk-CV
Mohamed Alaaeldin  Farouk-CVMohamed Alaaeldin  Farouk-CV
Mohamed Alaaeldin Farouk-CV
 
Level 1 Programme_IWCF Level 1 Programme
Level 1 Programme_IWCF Level 1 ProgrammeLevel 1 Programme_IWCF Level 1 Programme
Level 1 Programme_IWCF Level 1 Programme
 

Ähnlich wie Pycrashcourse3.0

Python@Unina - Theory
Python@Unina - TheoryPython@Unina - Theory
Python@Unina - TheoryNaLUG
 
What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018Marco Parenzan
 
Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!Marcello Missiroli
 
Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)STELITANO
 
Laboratorio Programmazione: Visibilita' e tipi di dato
Laboratorio Programmazione: Visibilita' e tipi di datoLaboratorio Programmazione: Visibilita' e tipi di dato
Laboratorio Programmazione: Visibilita' e tipi di datoMajong DevJfu
 
Coding class da scratch a python
Coding class  da scratch a pythonCoding class  da scratch a python
Coding class da scratch a pythonEnrico La Sala
 
Presentazione Oz - Mozart
Presentazione Oz - MozartPresentazione Oz - Mozart
Presentazione Oz - Mozartfede
 
Cattive abitudini e-lineeguida
Cattive abitudini e-lineeguidaCattive abitudini e-lineeguida
Cattive abitudini e-lineeguidaRobert Casanova
 
Linux@Unina
Linux@UninaLinux@Unina
Linux@UninaNaLUG
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)STELITANO
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)STELITANO
 

Ähnlich wie Pycrashcourse3.0 (20)

Python@Unina - Theory
Python@Unina - TheoryPython@Unina - Theory
Python@Unina - Theory
 
Inferno Limbo Italian
Inferno Limbo ItalianInferno Limbo Italian
Inferno Limbo Italian
 
What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018
 
Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!
 
05 1 intro-struttura
05 1 intro-struttura05 1 intro-struttura
05 1 intro-struttura
 
Pycon
PyconPycon
Pycon
 
Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)
 
Modulo 1 - Lezione 1
Modulo 1 - Lezione 1Modulo 1 - Lezione 1
Modulo 1 - Lezione 1
 
Bash intro
Bash introBash intro
Bash intro
 
Laboratorio Programmazione: Visibilita' e tipi di dato
Laboratorio Programmazione: Visibilita' e tipi di datoLaboratorio Programmazione: Visibilita' e tipi di dato
Laboratorio Programmazione: Visibilita' e tipi di dato
 
Bash Scripting
Bash ScriptingBash Scripting
Bash Scripting
 
Coding class da scratch a python
Coding class  da scratch a pythonCoding class  da scratch a python
Coding class da scratch a python
 
Corso python 2020 - Lezione 1
Corso python 2020 - Lezione 1Corso python 2020 - Lezione 1
Corso python 2020 - Lezione 1
 
Presentazione Oz - Mozart
Presentazione Oz - MozartPresentazione Oz - Mozart
Presentazione Oz - Mozart
 
Cattive abitudini e-lineeguida
Cattive abitudini e-lineeguidaCattive abitudini e-lineeguida
Cattive abitudini e-lineeguida
 
Py a5 python-text
Py a5 python-textPy a5 python-text
Py a5 python-text
 
Linux@Unina
Linux@UninaLinux@Unina
Linux@Unina
 
Python su ipad pycon 8
Python su ipad pycon 8Python su ipad pycon 8
Python su ipad pycon 8
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)
 

Mehr von rik0

Python intro
Python introPython intro
Python introrik0
 
Complex and Social Network Analysis in Python
Complex and Social Network Analysis in PythonComplex and Social Network Analysis in Python
Complex and Social Network Analysis in Pythonrik0
 
Game theory
Game theoryGame theory
Game theoryrik0
 
Social choice
Social choiceSocial choice
Social choicerik0
 
Social Network Analysis
Social Network AnalysisSocial Network Analysis
Social Network Analysisrik0
 
Clojure Interoperability
Clojure InteroperabilityClojure Interoperability
Clojure Interoperabilityrik0
 
Pydiomatic
PydiomaticPydiomatic
Pydiomaticrik0
 
Twcrashcourse
TwcrashcourseTwcrashcourse
Twcrashcourserik0
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved againrik0
 
Pyimproved
PyimprovedPyimproved
Pyimprovedrik0
 

Mehr von rik0 (10)

Python intro
Python introPython intro
Python intro
 
Complex and Social Network Analysis in Python
Complex and Social Network Analysis in PythonComplex and Social Network Analysis in Python
Complex and Social Network Analysis in Python
 
Game theory
Game theoryGame theory
Game theory
 
Social choice
Social choiceSocial choice
Social choice
 
Social Network Analysis
Social Network AnalysisSocial Network Analysis
Social Network Analysis
 
Clojure Interoperability
Clojure InteroperabilityClojure Interoperability
Clojure Interoperability
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
Twcrashcourse
TwcrashcourseTwcrashcourse
Twcrashcourse
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved again
 
Pyimproved
PyimprovedPyimproved
Pyimproved
 

Pycrashcourse3.0

  • 1. Introduzione al Linguaggio Python Enrico Franchi efranchi@ce.unipr.it Dipartimento di Ingegneria dell'Informazione Università di Parma 1
  • 2. Parlando del futuro... 2 We will perhaps eventually be writing only small modules that are identified by name as they are used to build larger ones, so that devices like indentation, rather than delimiters, might become feasible for expressing local structure in the source language. Donald E. Knuth, Structured Programming with go to Statements, 1974
  • 3. Introduzione 3 Python è concepito da Guido van Rossum alla fine degli anni ‘80 per Amoeba Pubblico 1991, stabile 1994. Linguaggio di alto livello ed orientato agli oggetti. Utilizzato per programmazione di sistema e di rete, e calcolo scientifico, applicazioni desktop, integrazione di videogiochi Si impone in ambito web/enterprise, con soluzioni come Zope/Plone, Django e Twisted.
  • 4. Piattaforma Python 4 “Very high-level language” (VHLL): sintassi pulita e scarna semantica semplice, regolare, potente object-oriented, ma multi-paradigma produttività tramite: modularità, uniformità, semplicità, pragmatismo Offre una ricca libreria standard di moduli Tanti strumenti ed estensioni di terze-parti Implementazioni in C, Java, .NET e Python stesso
  • 5. Comunità Python 5 Una forte comunità open-source Molti utenti (individui e compagnie) in tutti i campi Python Software Foundation (in Italia, Python Italia) Gruppi d’interesse per argomenti specifici Siti web, newsgroup, mailing list, ... Corsi, laboratori, tutorial, conferenze (Pycon Italia, quattro edizioni, fra le maggiori conferenze open italiana) Molti (specialmente in inglese...) in linea, su carta, o entrambi
  • 6. MESSAGGIO PROMOZIONALE 6 7-8-9 MAGGIO 2010 FIRENZE SCONTO STUDENTI, SESSIONI RECRUITING, ETC ETC http://www.pycon.it ~400 partecipanti
  • 7. Tempi di Apprendimento 7 Tempi necessari a un programmatore esperto per imparare bene...: Python vero e proprio (il linguaggio Python): 1-3 giorni builtin, metodi speciali, metaprogramming, ecc: 2-4 giorni la libreria standard (moduli fondamentali: os, sys, re, struct, itertools, collections, array, atexit, math, pickle, StringIO, heapq, weakref, threading...): 10-15 giorni tutta la libreria std: 30-50 giorni
  • 8. Python da 3000 metri (1) 8 Python è un linguaggio ad oggetti a tipizzazione dinamica e forte Tipizzazione forte: Gli errori di tipo sono sempre generati. Es. Stringhe non diventano interi e viceversa Ogni oggetto ha una classe, questa non cambia Tipizzazione dinamica Gli errori di tipo sono generati a runtime Duck typing
  • 9. Python da 3000 metri (II) 9 In Python tutto è un oggetto: Un numero, una stringa sono oggetti Gli oggetti sono oggetti (ehm...) Una funzione è un oggetto Una classe è un oggetto Gli oggetti sono cittadini di prima classe, possiamo manipolarli riccamente e comodamente (introspezione, etc.) Possiamo fare, in definitiva, tutto
  • 10. Versioni 10 Python è notevolmente compatibile fra versioni diverse Gli esempi di queste slides funzioneranno con Python 2.5 o Python 2.6, a meno che altrimenti specificato La maggior parte funzioneranno anche con Python 2.4 e Python 2.3 Python 3.x rappresenta il futuro, ma per ora si utilizza ancora 2.x, la transizione sarà morbida e lunga anni
  • 11. Hello, world! 11 print
“Hello,
world!”
  • 12. Dettagli implementativi 12 % cat hello.py Tipicamente Python viene #!/usr/bin/python compilato a byte-code e questo viene interpretato da print "Hello, world!" una macchina virtuale (come % python hello.py Java) Hello, world! Diversamente da Java la % chmod 755 hello.py % ./hello.py compilazione è trasparente Hello, world! per l’utente % python Python 2.5.1 (...) Possiamo anche usare ... l’interprete interattivo >>> print "Hello, world" Hello, world
  • 13. Interprete interattivo 13 L’interprete interattivo ufficiale ha >>> import os come prompt >>> >>> print “foo” foo Scriviamo comandi (statements) >>> os.getcwd() “/Users/enric/pycourse” che vengono byte-compilati ed >>> import sys >>> sys.stdout.write(“ciaon”) eseguiti ciao >>> def f(a): Se il comando valuta in un ... sys.stdout.write(a) ... return a espressione (es. un expression ... statement), l’espressione viene >>> f(“ciaon”) ciao stampata “ciaon”
  • 14. Letterali 14 >>> 12 >>> 3.2E10 Numeri interi, float 12 32000000000.0 >>> -27 >>> 'ciao' Base 10, 8, 16 -27 'ciao' >>> 0x6A >>> "ciao" Scientifica, fixpoint 106 'ciao' >>> 0.216 >>> 'c' 0.216 'c' Stringhe >>> [1, 2, "a", 2.32, "ciao"] Apici singoli o doppi [1, 2, 'a', 2.3199999999999998, 'ciao'] >>> '''Testo con Tre apici per testo multilinea ... piu' linee ... di testo''' Liste "Testo connpiu' lineendi testo" >>> """Ancora testo con ... piu' linee di testo""" Fra quadre, separate da "Ancora testo connpiu' linee di testo" virgola
  • 15. a = 16 print a a = 7.6 Variabili print a print a * 2 a = 'ciao' 15 i=1 In Python una variabile è print i, type(i) semplicemente un nome, un’ # => 1 <type 'int'> d = 217.217 etichetta, un modo per print d, type(d) # => 217.217 <type 'float'> riferirsi ad un oggetto s = '''Solito testo su piu' righe''' Le variabili non hanno tipo, print s, type(s) # => Solito testo gli oggetti hanno tipo # su piu' righe <type 'str'> d=2 Una etichetta può riferirsi ad print d, type(d) # => 2 <type 'int'> oggetti di diverso tipo nel i = 32761293836219387269827 print i, type(i) tempo # => 32761293836219387269827 <type 'long'> Assegnamento è statement
  • 16. Variabili/Oggetti 16 [java] Pet fido = new Dog(); tipo a compile-time tipo a runtime oggetto (dell’oggetto) (della variabile) variabile [python] fido = Dog()
  • 17. Controllo di flusso 17 Condizionale: Su if c’è poco da dire; while si if cond: usa rarissimamente, grazie ai statement else: generatori si preferisce for statement Siccome l’assegnamento è uno if cond: statement statement, non è possibile Iterazione unbounded: metterlo come condizione while cond: statement (fortunatamente) else: Disponibili break/continue statement else di for/while esegue su while cond: statement terminazione naturale (no exc/ cont/break/return)
  • 18. Liste (I) 18 >>> a = [1, 2, 'a', 'ciao', 4] La lista è in realtà un vector: >>> a[0] 1 accesso O(1) agli elementi >>> a[3] 'ciao' Inserimento e rimozione in >>> a[-1] 4 coda O(1) >>> a[10] Traceback (most recent call last): Controllo sugli indici File "<stdin>", line 1, in <module> IndexError: list index out of range (IndexError) >>> a.append(3) >>> a Indici negativi contano a [1, 2, 'a', 'ciao', 4, 3] >>> l = range(1, 4) partire dal fondo >>> a.extend(l) >>> a Possibilità di slice [1, 2, 'a', 'ciao', 4, 3, 1, 2, 3] >>> a.pop() 3
  • 19. Liste (II) 19 >>> a Presenti anche: [1, 2, 'a', 'ciao', 4, 3, 1, 2] >>> a[1:4] insert(i, o): inserisci o in [2, >>> 'a', 'ciao'] a[1:8:2] posizione i [2, 'ciao', 3, 2] >>> a[::-1] remove(v): togli la prima [2, 1, 3, 4, 'ciao', 'a', 2, 1] >>> a occorrenza di v [1, 2, 'a', 'ciao', 4, 3, 1, 2] count(v): ... index(v): ... sort(): ... ... Le liste sono mutabili
  • 20. Tuple 20 >>> t = tuple(a) “Simili” alle liste, tuttavia non >>> t[3] 'ciao' sono mutabili >>> t[-1] 2 Non possiamo aggiungere >>> t[1:] (2, 'a', 'ciao', 4, 3, 1, 2) elementi >>> a, b, c = t[:3] >>> print a, b, c Non possiamo cambiare 1 2 a elementi nella tupla >>> t = 1, 2, 'x' >>> l = list(t) Possiamo agire su questi, se >>> t.append(5) Traceback (most recent call last): non sono immutabili File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribut Per il resto funziona tutto >>> l.append(5) >>> l come previsto [1, 2, 'x', 5]
  • 21. Stringhe 21 Anche le stringhe sono >>> s = 'Hello, world! >>> s.strip() ' immutabili (= Java, != C++) 'Hello, world!' >>> s.replace('o', '0') 'Hell0, w0rld! ' Supportano slicing, indexing, >>> s.find('o') etc. 4 >>> s.rfind('o') 8 isdigit(), ... >>> s.upper() 'HELLO, WORLD! ' strip()... >>> s.center(60) ' Hello, world! find/rfind/index/rindex(ch) >>> s.startswith('He') True >>> s.split(', ') startswith/endswith(s) ['Hello', ' world! '] upper/lower/capitalize() ... andate a guardarli tutti!
  • 22. Operazioni su sequenze 22 >>> s = 'ciao' Stringhe, tuple e liste sono >>> m = 'mondo' >>> min(s) # <= 'a' sequenze >>> max(m) # <= 'o' >>> l = [1, 2, 3] Tutte le sequenze supportano >>> sum(l) # <= 6 >>> s + m # <= 'ciaomondo' alcune operazioni >>> s + l Traceback (most recent call last): min/max/sum File "<stdin>", line 1, in <module> TypeError: cannot concatenate 'str' and 'list' >>> list(s) + l + : concatenazione ['c', 'i', 'a', 'o', 1, 2, 3] >>> '=' * 10 S * n/ n * S: ripetizione '==========' >>> [1, ] * 10 el in S: appartenenza [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] >>> 'a' in s True >>> 'pippo' in l False
  • 23. Attenzione! 23 Sommare tanti oggetti immutabili funziona, ma crea ogni volta un nuovo elemento: Sommare 10 stringhe crea 10 nuove stringhe. E se sono 10000? Potrebbe essere l’ultimo pezzo di codice prima del licenziamento. Si usa join nella forma sep.join(elements) >>> lst = ['usr', 'local', 'lib'] >>> '/'.join(lst) 'usr/local/lib' >>> ' => '.join(lst) 'usr => local => lib' Per concatenare pezzi di path, usare os.path.join e i metodi presenti in os.path
  • 24. Statement For 24 For è il modo più comune di for ch in 'ciao mondo': print ch, iterare in Python print for n in range(10): Funziona con un generico print n iterabile for n in xrange(10): print n Esprime il concetto di “per for n in range(1, 20): ogni elemento in questa print n for n in xrange(1, 10000000000): sequenza” fai qualcosa print n Invece che usare una sequenza (finita), possiamo usare un generatore (potenzialmente infinito)
  • 25. Statement For 24 For è il modo più comune di for ch in 'ciao mondo': print ch, iterare in Python print for n in range(10): Funziona con un generico print n iterabile for n in xrange(10): print n Esprime il concetto di “per for n in range(1, 20): ogni elemento in questa print n for n in xrange(1, 10000000000): sequenza” fai qualcosa print n Invece che usare una sequenza (finita), possiamo Attenzione! range ritorna usare un generatore una lista xrange un iteratore. (potenzialmente infinito) Restituiscono intervalli [a, b)
  • 26. 99 Bottles of Beer 25 def pluralize(s, quantity): if quantity == 1: return s else: return s + "s" for how_many in range(99, 0, -1): print how_many, pluralize("bottle", how_many), "on the wall!" print "Take one down and pass it around,", how_many-1, print pluralize("bottle", how_many-1), print "of beer on the wall."
  • 27. More on for... 26 import os import shutil for fname in os.listdir(os.getcwd()): if fname.endswith(('pyc', 'pyo')): os.remove(fname) elif fname.endswith('py'): shutil.copy(fname, fname + '.bak')
  • 28. Dizionari 27 Array associativi/dizionari: >>> d = {'foo' : (1, 2, 3), ... 'bar' : (2, 3, 4)} coppie chiave-valore >>> d['foo'] (1, 2, 3) Operazioni tipicamente O(1) >>> d['baz'] Traceback (most recent call last): File "<stdin>", line 1, in <module> Implementazione KeyError: 'baz' esageratamente efficiente >>> d['bar'] = 'foo' >>> d {'foo': (1, 2, 3), 'bar': 'foo'} La chiave deve essere hashabile e immutabile (ecco perchè le stringhe...) Essenzialmente è una hash- table
  • 29. Dizionari (altri metodi) 28 D.pop(k[, d]): rimuove k (se presente) restituendo il valore corrispondente. Altrimenti restituisce d se specificato o da AttributeError D.popitem(): ritorna una coppia k-v (qualsiasi) D.get(k[,d]): ritorna il valore di k o d se k non è presente. Se non specificato d vale None. D.setdefault(k[,d]): D.get(k,d), setta D[k]=d se k non è in D D.update(E, **F): aggiunge le coppie k-v di E (ed F) a D
  • 30. Format (printf-on-steroids) 29 Le stringhe hanno un operatore % che permette di fare “format string” simili alla printf del C. -- man printf -- stringa % tupla: sostituzione posizionale: >>> '%s %d %s' % ('ciao', 9, ('h', 'p')) "ciao 9 ('h', 'p')" stringa % dizionario: sostituzione per nome: >>> 'Mi chiamo %(surname)s, %(fname)s %(surname)s.' % {'surname': 'Bond', 'fname' : 'James'} 'Mi chiamo Bond, James Bond.' Estremamente comodo. Usando %s si passa per str(obj), usando %r per repr(obj)
  • 31. Esempio dizionari 30 import sys filename = sys.argv[1] indx = {} try: f = open(filename) for n, line in enumerate(f): for word in line.split(): indx.setdefault(word, []).append(n) finally: f.close() for word in sorted(indx): # indice alfabetico print "%s:" % word, for n in indx[word]: print n, print
  • 32. I/O elementare 31 due funzioni built-in per l'input elementare input(prompt): immette qualsiasi espressione -- ne torna il valore raw_input(prompt): torna una stringa, rimuove il n a fine stringa un’istruzione per l'output elementare print <0+ espressioni separate da virgole> separa i risultati con uno spazio n alla fine (ma non se terminate con virgola) print di suo non fa formattazioni speciali print >> writable, <0+ espressioni separate da virgole>
  • 33. Eccezioni 32 Errori (e “anomalie” che non sono errori) “sollevano eccezioni” L’istruzione raise solleva un’eccezione Le eccezioni si propagano “lungo lo stack delle chiamate”, man mano terminando le funzioni, sinchè non vengono “catturate” Se non catturate, terminano il programma L'istruzione try/except può catturare eccezioni (anche: try/finally, e l'elegante with per implementare “RAII”)
  • 34. LBYL vs. EAFP 33 LBYL: Look before you leap # LBYL -- cattivo if user_name in employees: EAFP: Easier to ask forgiveness emp = than permission employees[user_name] else: Normalmente EAFP è la report_error(...) strategia migliore in Python Eccezioni relativamente poco costose #EAFP -- buono try: Atomicità, ... emp = employees[user_name] except KeyError: report_error(...)
  • 35. Vari tipi di try 34 try: # codice che potrebbe lanciare eccezione except IndexError, exc: # un tipo di errore # opzionalmente si mette ‘, nome’ per avere # l’oggetto eccezione da gestire except AnotherException: # gestione di un altro errore except: # gestione di ogni eccezione # tipicamente *NON* e' una buona pratica # a meno di non rilanciare raise # raise vuoto rilancia l'eccezione corrente finally: # questo codice e' eseguito *sempre* # codice di pulizia sia con errore che senza
  • 36. List Comprehensions 35 “Matematichese”: { f (x) | ∀x ∈S tali che p(x)} Python: [f(x) for x in seq if p(x)] Lista di tutti gli f(x) per tutti gli x contenuti in seq, a patto che p(x) sia vero. Simile a: tmp = [] for x in seq: if p(x): tmp.append(f(x))
  • 37. Generator Expressions 36 Si può fare restituendo un generatore, ovvero un iterabile “lazy” Il calcolo avviene solo mano a mano che i nuovi elementi sono “richiesti” Sintassi: (f(x) for x in seq if p(x)) Comodo con altre funzioni sum(f(x) for x in seq if p(x)) set(f(x) for x in seq if p(x)) dict((x, i) for (i, x) in enumerate(sorted(seq)))
  • 38. Funzioni 37 def <nome>(<parametri>): <corpo> <corpo> compilato, ma non subito eseguito <parametri>: 0+ variabili locali, inizializzate alla chiamata dagli <args> passati gli 0+ ultimi parameters possono avere "valori di default", <nome>=<expr> (expr è valutata una sola volta, quando def esegue) <parametri> può finire con *<nome> (tupla di arbitrari arg posizionali) e/o **<nome> (dict di arbitrari arg con nome)
  • 39. Esempio: somma di quadrati 38 def sumsq(a, b): return a*a+b*b print sumsq(23, 45) # => 2554 O, piú generale: def sumsq(*a): return sum(x*x for x in a) print sumsq(23, 45) # => 2554 print sumsq(23, 45, 44, 2) # => 4494 Minore livello di astrazione, + lento ma OK: def sumsq(*a): total = 0 for x in a: total += x*x return total
  • 40. “semplice wget” (GvR) 39 import sys import urllib import os def hook(*a): print '%s: %s' % (fn, a) for url in sys.argv[1:]: fn = os.path.basename(url) print url, "->", fn urllib.urlretrieve(url, fn, hook)
  • 41. Classi 40 class Stack(object): Classe Stack, eredita da def __init__(self, seq): object (come tutto) self._els = list(seq) Costruttore __init__, ha per def pop(self): return self._els.pop() parametro qualcosa di convertibile in lista def push(self, el): return self._els.append(el) Metodo pop delega al pop def __len__(self): della lista return len(self._els) >>> import stack Push “delega” all’append della >>> s = stack.Stack([1, 4, 7, 8]) lista >>> s.pop() 8 __len__, numero di elementi >>> s.push(3) >>> s.pop() 3
  • 42. Con documentazione 41 class Stack(object): 'Implements a stack' def __init__(self, seq): 'Create a new stack with elements from seq' self._elements = list(seq) def pop(self): 'Remove and return the head of the stack' return self._elements.pop() def push(self, element): 'Add el to the head of the stack' return self._elements.append(element) def __len__(self): return len(self._elements)
  • 43. class Duration(object): def __init__(self, minutes=0, seconds=0): if minutes < 0 or seconds < 0: raise ValueError("Duration times should be positive") self._duration = minutes * 60 + seconds 42 def minutes(self): return self._duration / 60 def seconds(self): return self._duration % 60 def __str__(self): return '%d:%02d' % (self.minutes(), self.seconds()) d1 = Duration(minutes=3) d2 = Duration(seconds=6) d3 = Duration(minutes=4, seconds=3) print d1.minutes(), d1.seconds() # => 3 0 print d1, d2, d3 # => 3:00 0:06 4:03
  • 44. Operatori 43 In Python sono disponibili operatori per i tipi definiti dall’utente (== C++, != Java) Python C++ uguale/diverso __eq__ operator== addizione __add__ operator+ minore __lt__ operator< [] __(g|s)etitem__ operator[] chiamata funz. __call__ operator() hash __hash__ ... conversioni __int__ operator int ... ... ...
  • 45. class Duration(object): ... def __add__(self, other): 44 return Duration(seconds=self._duration + other._duration) class Track(object): def __init__(self, artist, title, duration): self.artist = artist self.title = title self.duration = duration def __str__(self): return '%s - %s - %s' % (self.artist, self.title, self.duration)
  • 46. class MusicRecord(object): def __init__(self, title, tracks): self.title = title if not tracks: raise ValueError("Empty track list.") self.tracks = tuple(tracks) 45 def is_compilation(self): artists = set(track.artist for track in self.tracks) return len(titles) > 1 def get_duration(self): return sum((track.duration for track in self.tracks), Duration()) def get_artist(self): if self.is_compilation(): return 'AA. VV.' else: return self.tracks[0].title def get_title(self): return self.title
  • 47. lz = 'Led Zeppelin' tracks = [ Track(lz, 'Whole Lotta Love', Duration(5, 34)), Track(lz, 'What Is and What Should Never Be', 46 Duration(4, 44)), Track(lz, 'The Lemon Song', Duration(6, 19)), Track(lz, 'Thank You', Duration(4, 47)), Track(lz, 'Heartbreaker', Duration(4, 14)), Track(lz, "Living Loving Maid (She's Just a Woman)", Duration(2, 39)), Track(lz, 'Ramble On', Duration(4, 23)), Track(lz, 'Moby Dick', Duration(4, 21)), Track(lz, 'Bring It On Home', Duration(4, 20)) ] lz2 = MusicRecord('Led Zeppelin II', tracks) print lz2.get_duration() # => 41:21
  • 48. Properties (I) 47 class A(object): Abbiamo scelto di usare per def __init__(self, foo): Track attributi pubblici self._foo = foo def get_foo(self): Supponiamo di volere print 'got foo' return self._foo aggiungere controlli, per esempio validare gli def set_foo(self, val): print 'set foo' assegnamenti, oppure self._foo = val renderli impossibili... foo = property(get_foo, set_foo) bisognerebbe modificare il a = A('ciao') codice? print a.foo # => 'got foo' property: sintassi di attributi, # => 'ciao' a.foo = 'bar' sotto chiama funzioni # => 'set foo'
  • 49. Properties (II) 48 E se non vogliamo il setter del tutto? Non mettiamolo! class A(object): def __init__(self, foo): self._foo = foo def get_foo(self): print 'got foo' return self._foo foo = property(get_foo) a = A('ciao') print a.foo # => 'got foo' # => 'ciao' a.foo = 'bar' # Traceback (most recent call last): # File "prop_example2.py", line 15, in <module> # a.foo = 'bar' # AttributeError: can't set attribute'
  • 50. Properties (III) 49 Snelliamo la sintassi. Possiamo usare un decoratore class A(object): def __init__(self, foo): self._foo = foo @property def foo(self): print 'got foo' return self._foo a = A('ciao') print a.foo # => 'got foo' # => 'ciao' a.foo = 'bar' # Traceback (most recent call last): # File "prop_example2.py", line 15, in <module> # a.foo = 'bar' # AttributeError: can't set attribute'
  • 51. Properties (IV) 50 Con Python 2.6, anche con setter: class A(object): def __init__(self, foo): self._foo = foo @property def foo(self): print 'got foo' return self._foo @foo.setter def foo(self, value): print 'set foo' self._foo = value a = A('ciao') a.foo = 'bar' # => 'set foo'
  • 52. class Track(object): def __init__(self, artist, title, duration): self._artist = artist self._title = title self._duration = duration 51 @property def artist(self): return self._artist @property def title(self): return self._title @property def duration(self): return self._duration def __str__(self): return '%s - %s - %s' % (self.artist, self.title, self.duration)
  • 53. class MusicRecord(object): def __init__(self, title, tracks): self.title = title if not tracks: raise ValueError("Empty track list.") 52 self.tracks = tuple(tracks) self._artists = set(track.artist for track in self.tracks) self._duration = sum((track.duration for track in self.tracks), Duration()) @property def is_compilation(self): return len(self._titles) > 1 @property def duration(self): return self._duration @property def artist(self): if self.is_compilation: return 'AA. VV.' else: return self.tracks[0].title
  • 54. Adulti e vaccinati... 53 Possiamo impedire l’accesso usando le properties Possiamo usare meta-programmazione1 per scrivere meno codice Es... namedtuple, definita nella libreria standard Track = collections.namedtuple( 'Track', ['title', 'artist', 'duration']) 1. meta-programmazione: scrittura di programmi che scrivono o modificano altri programmi (o se stessi) come i loro dati
  • 55. Decoratori (I) 54 def log(f): Un decoratore nella sua def _aux(*args, **kargs): generalità è una funzione che print 'Called %s' % f.__name__ return f(*args, **kargs) accetta una funzione come return _aux parametro e ne restituisce @log def double(n): una versione modificata return 2 * n @deco class eg(object): def f(...): ... @log def foo(self): equivale a: print 'foo' def f(...): ... double(10) # => Called double eg().foo() f = deco(f) # => Called foo # => foo
  • 56. Decoratori (II) 55 Esempio da Django (web framework) from django.contrib.auth.decorators import login_required @login_required def my_view(request): ... Un decoratore può anche avere argomenti I decoratori si possono combinare class Bank(object): # ... @with_logger(default_logger) @atomic def transfer(self, from_, to, amount): self.accounts[from_] -= amount # raises NegativeAccountError self.accounts[to] += amount
  • 57. Dinamismo e introspezione 56 Quando un attributo di un oggetto non viene trovato, se è definito il metodo __getattr__ Se si, viene chiamato con come parametro il nome dell’attributo cercato Esempio: delega [prossima slide] Funzione getattr: prende un attributo per nome f.foo
 
getattr(f,
‘foo’)
  • 58. Stack (con delega) 57 class Stack(object): delegates = dict(pop='pop', push='append') def __init__(self, seq): self._elements = list(seq) def __getattr__(self, value): try: delegate_name = Stack.delegates[value] except KeyError: raise AttributeError else: delegate_method = getattr(self._elements, delegate_name) return delegate_method
  • 59. Convenzioni (PEP8) 58 http://www.python.it/doc/articoli/pep-8.html
  • 60. Importare Moduli 59 import nomemodulo from un.certo.package import nomemodulo poi si usa nomemodulo.foo ci sono abbreviazioni (non necessariamente buone...): accorciare i nomi con la clausola as: import itertools as it poi si usa it.izip from itertools import izip from itertools import *
  • 61. Esempio di Import 60 import math print math.atan2(1, 3) # emette 0.321750554397 print atan2(1, 3) # solleva un'eccezione NameError from math import atan2 inietta atan2 nel namespace corrente comodo in interattivo, ma spesso illeggibile in “veri” programmi: evitare! peggio ancora (evitare COME LA PESTE!): from math import *
  • 62. Definire Moduli 61 ogni sorgente Python wot.py è un modulo basta fare import wot deve vivere nella path d'importazione ...che è la lista path nel modulo sys, ogni elemento una stringa che nomina un dir (o zipfile, ...) contenente moduli Python pure importabili: file di bytecode (wot.pyc), automaticamente creati dal compilatore Python quando importi un .py pure importabili: estensioni binarie (wot.pyd), scritte in C (or pyrex, SWIG, ...)
  • 63. Persistenza 62 cPickle: tutti gli oggetti sono facilmente e automaticamente serializzabili su disco Modulo shelve Si usa come un dizionario, offre gratis persistenza su disco per strutture chiave-valore Esigenze maggiori? SQLite integrato con Python Non basta? PostgreSQL Scriptabile in Python Accessibile da Python (+ ORM, SQLAlchemy)
  • 64. Rete 63 Modulo socket, offre socket C-like (ma più semplici da usare) Moduli asyncore: programmazione asincrona semplice Moduli poplib, urllib, smtplib, email, imaplib Moduli serverside: TCPServer, TCPForkingServer, TCPThreadingServer, UDP... Twisted (asyncrono, altissima efficienza) Tornado (facebook)
  • 65. Interfacce grafiche 64 Tkinter Multipiattaforma, libreria standard, bruttarello Qt Piattaforma ricchissima, cross-platform, ++ wx Cross-platform, ... [non inneschiamo flames] GTK, Cocoa, WinAPI, + .Net con IronPython, Swing con Jython, FLTK...
  • 66. Calcolo scientifico 65 PIL Manipolazione immagini Numpy+Matplotlib Calcolo numerico, simile a Matlab/Octave Scipy Ulteriori librerie http://www.scipy.org/
  • 67. Web 66 cgi (sconsigliato)/fastcgi WSGI: modulo di medio livello per interfacciarsi con i server Django: framework completo, molto usato Nevow: framework completo basato su Twisted Zope2/3: “mega framework” Google App Engine (+web.py ev. Django) web.py: modulo minimalista, facile comprensione
  • 68. Q&A Help System Ancora su Classi e Istanze 67 Generatori & Attributi di Classe Generatori Infiniti Scope With Statement Duck Typing
  • 69. Help system 68 >>> help(os.getcwd) La funzione help() da aiuto su getcwd(...) getcwd() -> path una funzione/classe/modulo Return a string representing the current working direc etc. >>> help(sys) Help on built-in module sys: Se chiamata sull’istanza di NAME una classe (quindi anche un sys numero o una stringa) da FILE informazioni sulla classe (built-in) Di fatto va a leggere le MODULE DOCS http://www.python.org/doc/current/lib/module-sys.h ‘docstring’ (vediamo poi...) DESCRIPTION This module provides access to some objects used or Consideriamo anche pydoc interpreter and to functions that interact strongly with
  • 70. Help system 68 >>> help(os.getcwd) getcwd(...) getcwd() -> path Return a string representing the current working directory. >>> help(sys) Help on built-in module sys: NAME sys FILE (built-in) MODULE DOCS http://www.python.org/doc/current/lib/module-sys.html DESCRIPTION This module provides access to some objects used or maintained by the interpreter and to functions that interact strongly with the interpreter.
  • 71. >>> help(sys.stdout) Help on file object: class file(object) | file(name[, mode[, buffering]]) -> file object | | Open a file. The mode can be 'r', 'w' or 'a' for reading (default), | writing or appending. The file will be created if it doesn't exist 69 | when opened for writing or appending; it will be truncated when | opened for writing. Add a 'b' to the mode for binary files. ... bash> pydoc os.path.join Help on function join in os.path: os.path.join = join(a, *p) Join two or more pathname components, inserting '/' as needed bash> pydoc -p 8080 pydoc server ready at http://localhost:8080/ % python >>> help() Welcome to Python 2.5! This is the online help utility. help> To Q&A
  • 72. >>> help(sys.stdout) Help on file object: class file(object) | file(name[, mode[, buffering]]) -> file object | | Open a file. The mode can be 'r', 'w' or 'a' for reading (default), | writing or appending. The file will be created if it doesn't exist 69 | when opened for writing or appending; it will be truncated when | opened for writing. Add a 'b' to the mode for binary files. ... bash> pydoc os.path.join Help on function join in os.path: os.path.join = join(a, *p) Join two or more pathname components, inserting '/' as needed bash> pydoc -p 8080 pydoc server ready at http://localhost:8080/ % python >>> help() Welcome to Python 2.5! This is the online help utility. help> To Q&A
  • 73. Attributi di istanza e di classe 70 class A(object): Fino ad ora abbiamo visto cattr = [] def __init__(self): come aggiungere attributi alle self.iattr = [] istanze delle classi (banale) def add(self, obj): self.cattr.append(obj) Sappiamo che le funzioni, in self.iattr.append(obj) un certo senso sono attributi a1 = A() degli “oggetti classe” a2 = A() a1.add('x') print a1.cattr, a1.iattr Se definiamo un attributo nel # => ['x'], ['x'] corpo di una classe, è un print a2.cattr, a2.iattr # => ['x'], [] attributo di classe a2.add('y') print a1.cattr, a1.iattr # => ['x', 'y'], ['x'] print a2.cattr, a2.iattr # => ['x', 'y'], ['y']
  • 74. Metodi di classe 71 I metodi di classe si class A(object): @classmethod definiscono con il decoratore def say(cls, m): classmethod print cls.__name__, m Hanno come primo A.say('hello') # => A hello argomento l’oggetto classe a = A() Accedono ad attributi di a.say('hello') # => A hello classe (ma non d’istanza) Convenzionalmente, chiamiamo il primo parametro cls e non self To Q&A
  • 75. With statement 72 with file('foo.txt') as f: for line in f: print line.strip() with gestisce un “contesto”, quando si esce dal blocco with (con eccezione o meno), viene gestita la chiusura di file Simile agli idiomi RAII (resource allocation is initialization) di C++, ma molto più facile da gestire
  • 76. Vecchio esempio... 73 import sys filename = sys.argv[1] indx = {} with open(filename) as f: for n, line in enumerate(f): for word in line.split(): indx.setdefault(word, []).append(n) # mostriamola in indice alfabetico for word in sorted(indx): print "%s:" % word, for n in indx[word]: print n, print To Q&A
  • 77. Generatori 74 def couples(l): funzioni con yield invece di i = 0 return length = len(l) while i < length-1: ogni chiamata costruisce e yield l[i], l[i+1] torna un iteratore (oggetto i += 1 con metodo next, adatto a lst = [1, 2, 3, 4, 5, 6] essere iterato in un ciclo for) for pairs in couples(lst): la fine della funzione solleva print pairs StopIteration (1, 2) (2, 3) (3, 4) (4, 5) (5, 6)
  • 78. Generatori Infiniti 75 def fibonacci(): i = j = 1 while True: r, i, j = i, j, i + j yield r for rabbits in fibonacci(): if rabbits > 100: break else: print rabbits, 1 1 2 3 5 8 13 21 34 55 89 To Q&A
  • 79. Classi 76 class <nome>(<basi>): <corpo> <corpo> è di solito una serie di istruzioni def e assegnazioni; i nomi definiti o assegnati divengono attributi del nuovo oggetto classe <nome> (le funzioni divengono "metodi") gli attributi di una qualsiasi base sono anche attributi della nuova classe, se non "overridden" (assegnati o definiti nel corpo) Iniziare con singolo _ indica essere privati
  • 80. Istanziare una Classe 77 class eg(object): cla = [] # attrib. di classe def __init__(self): # inizializzatore self.ins = {} # attrib. d'istanza def meth1(self, x): # un metodo self.cla.append(x) def meth2(self, y, z): # altro metodo self.ins[y] = z es1 = eg() es2 = eg()
  • 81. Classi e Istanze 78 print es1.cla, es2.cla, es1.ins, es2.ins [] [] {} {} es1.meth1(1); es1.meth2(2, 3) es2.meth1(4); es2.meth2(5, 6) print es1.cla, es2.cla, es1.ins, es2.ins [1, 4] [1, 4] {2: 3} {5: 6} print es1.cla is es2.cla True print es1.ins is es2.ins False
  • 82. Risoluzione degli Attributi 79 inst.method(arg1, arg2) type(inst).method(inst, arg1, arg2) inst.nome [[che sia poi chiamato o meno!]] (i "descrittori" possono alterarlo...) prova inst.__dict__['nome'] prova type(inst).__dict__['nome'] prova ciascuna delle type(inst).__bases__ prova type(inst).__getattr__(inst, 'nome') se tutto fallisce, raise AttributeError To Q&A
  • 83. Scope delle variabili 80 I parametri di una funzione e ogni variabile che viene legata (con assegnamento o statement come def o class) nel corpo di una funzione costituisce il namespace della funzione (local scope) Lo scope di queste variabili è tutto il corpo della funzione (ma usarle prima che siano state legate è un errore) Le variabili non locali sono dette globali, il loro scope è il modulo intero Normalmente non ci sono motivi per usarle To Q&A
  • 84. Scope delle variabili 80 I parametri di una funzione e ogni variabile che viene legata (con assegnamento o statement come def o class) nel corpo di una funzione costituisce il namespace None funzione (local della a= scope) if s.startswith(t): a = s[:4] Lo scope di queste variabili è tutto il corpo della else: funzione (ma usarle prima tche siano state legate a= è un errore) print a Le variabili non locali sono dette globali, il loro SBAGLIATO scope è il modulo intero Normalmente non ci sono motivi per usarle To Q&A
  • 85. Scope delle variabili 80 I parametri di una funzione e ogni variabile che viene legata (con assegnamento o statement come def o class) nel corpo di una funzione costituisce il namespace della funzione (local scope) if s.startswith(t): a = s[:4] Lo scope di queste variabili è tutto il corpo della else: funzione (ma usarle prima tche siano state legate a= è un errore) print a Le variabili non locali sono dette globali, il loro GIUSTO scope è il modulo intero Normalmente non ci sono motivi per usarle To Q&A
  • 86. Pensiamo a Java/C++... 81 Nei linguaggi con un type-system derivato da C+ + chiediamo che i parametri di una certa funzione abbiano un dato tipo (o siano di un sottotipo) Questo è poco flessibile: programmare per un interfaccia Interfacce di Java (vero polimorfismo din.) Templates di C++ (polimorfismo statico) Sono soluzioni con problemi
  • 87. Libri, ricerca per titolo 82 Chiamare su una lista che class Book(object): def __init__(self, title, author): contiene un “non libro” self.title = title self.author = author lancia eccezione def find_by_title(seq, title): Eppure non gestiamo for item in seq: if type(item) == Book: # horrible nemmeno sottoclassi if item.title == title: return item Peggior codice possibile, else: raise TypeError inoltre stiamo risolvendo def find_by_author(seq, author): un non-problema for item in seq: if type(item) == Book: # horrible if item.author == author: return item else: raise TypeError
  • 88. Libri, ricerca per titolo 82 Chiamare su una lista che contiene un “non libro” lancia eccezione Eppure non gestiamo nemmeno sottoclassi Peggior codice possibile, inoltre stiamo risolvendo un non-problema
  • 89. Libri, ricerca per titolo 83 Ora gestiamo sottoclassi class Book(object): def __init__(self, title, author): self.title = title Eppure noi non usiamo mai self.author = author il fatto che la cosa sia un def find_by_title(seq, title): libro for item in seq: if isinstance(item, Book): # bad if item.title == title: Solo che ha un titolo return item else: Solo che ha un autore raise TypeError Cosa succede se abbiamo def find_by_author(seq, author): for item in seq: una classe Song? if isinstance(item, Book): # bad if item.author == author: return item else: raise TypeError
  • 90. Libri, ricerca per titolo 83 Ora gestiamo sottoclassi Eppure noi non usiamo mai il fatto che la cosa sia un def find_by_title(seq, title): libro for item in seq: if isinstance(item, Book): # bad if item.title == title: Solo che ha un titolo return item else: Solo che ha un autore raise TypeError Cosa succede se abbiamo def find_by_author(seq, author): for item in seq: una classe Song? if isinstance(item, Book): # bad if item.author == author: return item else: raise TypeError
  • 91. Libri, ricerca per titolo 83 Ora gestiamo sottoclassi class Song(object): def __init__(self, title, author): self.title = title Eppure noi non usiamo mai self.author = author il fatto che la cosa sia un def find_by_title(seq, title): libro for item in seq: if isinstance(item, Book): # bad if item.title == title: Solo che ha un titolo return item else: Solo che ha un autore raise TypeError Cosa succede se abbiamo def find_by_author(seq, author): for item in seq: una classe Song? if isinstance(item, Book): # bad if item.author == author: return item else: raise TypeError
  • 92. Libri e canzoni 84 La cosa più semplice è la migliore class Book(object): I programmatori tendono a non def __init__(self, t, a): self.title = t scrivere codice a caso self.author = a Abbiamo sempre eccezioni def find_by_title(seq, title): for item in seq: lanciate if item.title == title: return item I test servono apposta per def find_by_author(seq, author): prendere ‘sta roba for item in seq: if item.author == author: return item
  • 93. E se avessimo film? 85 I film hanno sempre un titolo, ma non hanno un autore, bensì un regista find_by_title dovrebbe funzionare, find_by_author, no Interfaccia per Book e Song. E per Movie? Design Pattern o duplicazione di codice Ruota quadrata strade per ruote quadrate Con il duck typing non dobbiamo cambiare nulla
  • 94. def find_by(seq, **kwargs): for obj in seq: To Q&A for key, val in kwargs.iteritems(): try: if getattr(obj, key) != val: break except KeyError: break else: return obj raise NotFound print find_by(books, title='Python in a Nutshell') print find_by(books, author='M. Beri') print find_by(books, title='Python in a Nutshell', author='A. Martelli') try: print find_by(books, title='Python in a Nutshell', author='M.Beri') print find_by(books, title='Python in a Nutshell', pages=123) except NotFound: pass

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n