Il terzo capitolo è sostanzialmente una spiegazione di come usare le classi .NET in IronPython, con un po’ di introduzione ad essere per chi arriva da Python.
I post precedenti sono: introduzione a Python, introduzione e il preambolo
Interpretare MSDN per essere usata con IronPython è piuttosto semplice. La traduzione è quasi 1:1 dato che l’integrazione di IronPython è pressoché completa.
.NET da IronPython
Salto in toto l’introduzione a .NET dato il posto in cui mi trovo a postare, però vi mostro un esempio di uso di Windows Forms in IronPython (più o meno il minimo indispensabile per visualizzare una form dalla shell dell’interprete):
>>> import clr
>>> clr.AddReference('System.Windows.Forms')
>>> from System.Windows.Forms import Application, Form
>>> form = Form()
>>> form.Text = 'Hello World' # set the title
>>> Application.Run(form) # main loop
Le linee
>>> form = Form()
>>> form.Text = 'Hello World' # set the title
possono essere anche condensate passando le proprietà al costruttore:
>>> form = Form(Text='Hello World')
Alcuni tipi .NET come stringhe, numeri e booleani sono identità dei corrispondenti tipi Python.
Il libro si concentra su Windows Forms anche per introdurre vari elementi del Common Type System come le collection e i delegate.
Ad esempio per aggiungere un controllo alla collezione della form:
>>> form = Form()
>>> label = Label()
>>> form.Controls.Add(label)
Ovviamente è possibile usare IronPython Studio per disegnare e configurare le form.
Consiglio di usare sempre dir(object) e help() per ispezionare gli oggetti durante lo sviluppo tramite interprete a linea di comando, a volte risparmia qualche lookup sull’MSDN ;-)
Attributi come Form.Controls
che implementano IList
sono indicizzabili in Python anche se eventuali array tipizzati .NET non sono sempre interscambiabili con le liste Python. Se un oggetto implementa IEnumerable
esso è iterabile in Python (potete usare il for
o le list comprehension).
Gli oggetti che espongono Count
o Length
(i container) supportano len() e al posto di Contains
potete usare in
per controllare se un oggetto è contenuto in un altro. Ecco un po’ di esempi:
>>> dir(form.Controls) # inspect
['Add', 'AddRange', 'Clear', 'Clone', 'Contains', 'ContainsKey', 'CopyTo', 'Count', 'Equals', 'Find', ...]
>>> from System.Windows.Forms import Label
>>> label = Label()
>>> form.Controls.Add(label) # add the label to the collection
>>> form.Controls
<System.Windows.Forms.Form+ControlCollection ...>
>>> form.Controls[0] # the collection is indexable
<System.Windows.Forms.Label ...>
>>> [c for c in form.Controls] # the collection is iterable
[<System.Windows.Forms.Label ...]
>>> len(form.Controls) # the collection supports len()
1
>>> label in form.Controls # the collection supports in
True
>>> # instead of Add you can also use the Parent property
>>> label2 = Label()
>>> label2.Parent = form
>>> label2 in form.Controls
True
Le struct ovviamente sono supportate in maniera trasparente, come anche le enumerazioni. Potete usare l’operatore |
per combinare eventuali flag.
Gestione eventi
La gestione eventi in IronPython è davvero molto semplice. C# usa i delegate per wrappare i metodi facendo, IronPython usa direttamente le funzioni native di Python, per cui non c’è bisogno di delegate:
form = Form()
def onMouseMove(sender, event): # sender is the object
print event.X, event.Y
form.MouseMove += onMouseMove # add the handler to the event
Ereditare tipi .NET
Anche qui la questione è piuttosto trasparente. L’integrazione è totale quindi basta ereditare il tipo .NET con la sintassi Python ed istanziarlo come una normale classe:
class MainForm(Form):
def __init__(self):
self.Text = "Hello World"
self.FormBorderStyle = FormBorderStyle.Fixed3D
self.Height = 150
mainForm = MainForm()
__init__
è il costruttore, self
rappresenta la nuova istanza (il this
implicito in C#)
Ecco tutto.