• Non ci sono risultati.

Metaprogramming in Python

N/A
N/A
Protected

Academic year: 2021

Condividi "Metaprogramming in Python"

Copied!
18
0
0

Testo completo

(1)

Linguaggi dinamici – A.A. 2010/2011

1

Metaprogramming

in Python

(2)

Introduzione

Il Python mette a disposizione tutta una serie di meccanismi per il metaprogramming

Introspezione di classi e metodi

Esecuzione di codice generato dinamicamente

Gestione degli errori a runtime

Tali funzionalità sono presenti sotto forma di

funzioni builtin e di moduli

(3)

Linguaggi dinamici – A.A. 2010/2011

3

Introspezione a livello di sistema

E' possibile invocare funzionalità di

introspezione già a livello di interprete da riga di comando

L'interprete interattivo ci fornisce informazioni sui moduli installati e sulle loro caratteristiche

Modulo di sistema sys

Fornisce informazioni sull'interprete e sull'ambiente operativo

import sys

(4)

Introspezione a livello di sistema

Alcuni esempi di introspezione

Nome dell'eseguibile “interprete”: sys.executable

Versione dell'eseguibile “interprete”: sys.version

Nome della piattaforma:

sys.platform

Limiti di sistema:

sys.maxint, sys.maxsize, sys.maxunicode

Argomenti da linea di comando:

sys.argv

Percorso di ricerca dei moduli: sys.path

(5)

Linguaggi dinamici – A.A. 2010/2011

5

Introspezione a livello di sistema

Una delle variabili esportate da sys permette di ottenere l'insieme dei nomi dei moduli visibili dall'interprete

sys.modules: dizionario contenente coppie chiave-valore, in cui:

alla chiave corrisponde il nome completo del modulo

al valore corrisponde il percorso completo della versione compilata del modulo

(6)

Introspezione a livello di modulo

La funzione dir() elenca i simboli di un simbolo generico

Simbolo:

Nome modulo (oggetto di tipo classe)

Nome istanza oggetto

Variabile

Funzione

Se invocata senza alcun argomento, dir() restituisce i simboli attualmente visibili all'interprete

ESEMPI:

Person.py

(7)

Linguaggi dinamici – A.A. 2010/2011

7

Introspezione degli oggetti

E' possibile estrarre informazioni specifiche dalle classi e dagli oggetti

Nome

Tipo di dato dell'oggetto

Identità

Metodi ed attributi

Relazioni con altre classi

(8)

Introspezione degli oggetti

Nome di un simbolo associato ad un oggetto:

simbolo privato __name__

nome_simbolo.__name__

Tipo di un simbolo associato ad un oggetto:

funzione type()

type(object)

Id (identità) di un oggetto: funzione id()

id(object)

Confronto di identità: funzione is()

obj_a is obj_b

ESEMPI:

type.py id.py

(9)

Linguaggi dinamici – A.A. 2010/2011

9

Introspezione degli oggetti

Controllo esistenza di uno specifico attributo in un oggetto: funzione hasattr()

hasattr(object, attribute)

Restituisce True se object ha l'attributo attribute

L'attributo può essere una variabile/funzione

Recupero di uno specifico attributo da un oggetto: funzione getattr()

getattr(object, attribute)

Equivalente ad object.attribute

Attribute può essere il contenuto di una variabile stringa; pertanto, gli attributi possono essere

specificati dinamicamente!

ESEMPI:

attr.py

(10)

Introspezione degli oggetti

Controllo invocabilità di un oggetto: funzione callable()

callable(object)

Restituisce True se object è invocabile

Relazioni con altre classi:

metodi isinstance() e issubclass()

ESEMPI:

interrogate.py

(11)

Linguaggi dinamici – A.A. 2010/2011

11

Subroutine anonime

E' possibile assegnare a variabili delle funzioni (che vengono perciò chiamate subroutine

anonime)

In Python, la funzioni anonime sono chiamate funzioni lambda

In onore ad Alonzo Church (1903-1995), ideatore del lambda-calcolo e precursore dei linguaggi funzionali

(12)

Subroutine anonime

Una funzione anonima è definita tramite la parola chiave lambda

variabile = lambda lista_var : espressione

Ad esempio, la seguente assegnazione associa alla variabile f la funzione anonima x^2

f = lambda x: x^2

La variabile f punta all'oggetto “funzione

anonima” rappresentato dall'espressione x^2

type(f) restituisce, conseguentemente, il tipo function

ESEMPI:

switch.py

(13)

Linguaggi dinamici – A.A. 2010/2011

13

Closure

In Python, le closure (blocchi di codice cui sono associati una o più variabili) possono essere

implementate in due modi diversi:

definendo una funzione che restituisce una funzione lambda

definendo una funzione che a sua volta definisce e restituisce un'altra funzione

ESEMPI:

closure1.py closure2.py

(14)

Generazione dinamica di codice

Il Python mette a disposizione meccanismi per valutare espressioni e statement

eval(expr): l'espressione viene analizzata sintatticamente e valutata

exec(stmt): lo statement viene analizzato sintatticamente ed interpretato

execfile(file): il file viene letto, analizzato sintatticamente ed interpretato

E' possibile passare due ulteriori parametri:

globals (un dizionario di variabili globali), e

ESEMPI:

eval.py exec.py execfile.py

(15)

Linguaggi dinamici – A.A. 2010/2011

15

Generazione dinamica di codice

Se la stessa stringa deve essere eseguita più volte, conviene precompilarla

compile(source, filename, mode)

Compila la stringa source (o, in alternativa, il file di nome filename)

Il parametro mode specifica l'identità dell'oggetto prodotto:

'exec' → sequenza di statement

'eval' → espressione

'single' → un singolo statement interattivo

Viene restituito un code object che può essere valutato con eval() o interpretato con exec()

ESEMPI:

compile.py

(16)

Gestione degli errori a runtime

Il Python mette a disposizione il costrutto

try-except-else-finally per gestire le eccezioni

try:

blocco di codice

except lista_eccezioni:

blocco di codice

else: # eseguito in assenza di eccezioni

blocco di codice

finally: # eseguito sempre

ESEMPI:

exc1.py

(17)

Linguaggi dinamici – A.A. 2010/2011

17

Gestione degli errori a runtime

E' possibile ignorare alcune eccezioni associando la relativa lista di nomi allo statement nullo pass

try:

blocco di codice

except lista_eccezioni:

pass

ESEMPI:

exc2.py

(18)

Gestione degli errori a runtime

Le eccezioni possono essere invocate dal programmatore tramite l'istruzione raise raise NomeEccezione(Lista_Argomenti)

L'elenco delle eccezioni è consultabile al seguente indirizzo:

http://docs.python.org/library/exceptions.html

E' possibile definire nuove eccezioni estendendo la classe Exception

ESEMPI:

exc3.py Myerror.py

Riferimenti

Documenti correlati

 Per importare nell'editor un intervallo di righe della history, si invoca edit con gli identificatori del primo e dell'ultimo comando, separati da :.

 Ogni stringa è memorizzata nella memoria del calcolatore come una lista di caratteri..  >>> myString

 Creazione di una classe contenente il codice dell'applicazione grafica (widget, handler).  Esecuzione del

 Selezioniamo il bottone più a sinistra nella casella dei pulsanti.  Abilitiamo il radio button “Pulsante stock” (che attiva una delle

 Python mette a disposizione il modulo logging per l'implementazione di molteplici canali

 PyRO usa un proprio object name server (NS) per individuare gli oggetti remoti.  Gli oggetti remoti devono essere registrati presso

(2) Arrays with a size of 1 along a particular dimension act like the array with the largest size along that dimension. The values of the array are assumed to be the same along

• Le funzioni Numpy sono efficienti per lavorare sugli array, ma possono lavorare anche sugli scalari. • Le funzioni contenute in math sono più efficienti sugli scalari rispetto