Chapter 1. A new language for .NET

This chapter covers

  • An introduction to IronPython

  • Python and dynamic languages on .NET

  • The IronPython interactive interpreter

  • Live object introspection with help and dir

The .NET framework was launched in 2000 and has since become a popular platform for object-oriented programming. Its heart and soul is the Common Language Runtime (CLR), which is a powerful system including a just-in-time compiler, built-in memory management, and security features. Fortunately, you can write .NET programs that take advantage of many of these features without having to understand them, or even be aware of them. Along with the runtime comes a vast array of libraries and classes, collectively known as the framework classes. Libraries available in the .NET framework include the Windows Forms and Windows Presentation Foundation (WPF)[1] graphical user interfaces, as well as libraries for communicating across networks, working with databases, creating web applications, and a great deal more.

The traditional languages for writing .NET programs are Visual Basic.NET, C#, and C++.[2] IronPython is a .NET compiler for a programming language called Python, making IronPython a first-class .NET programming language. If you’re a .NET developer, you can use Python for tasks from web development to creating simple administration scripts, and just about everything in between. If you’re a Python programmer, you can use your favorite language to take advantage of the .NET framework.

IronPython isn’t cast in the same mold as traditional .NET languages, although there are similarities. It’s a dynamically typed language, which means a lot of things are done differently and you can do things that are either impossible or more difficult with alternative languages. Python is also a multi-paradigm language. It supports such diverse styles of programming as procedural and functional programming, object-oriented programming, metaprogramming, and more.

Microsoft has gone to a great deal of trouble to integrate IronPython with the various tools and frameworks that are part of the .NET family. They’ve built specific support for IronPython into the following projects:

  • Visual Studio—The integrated development environment

  • ASP.NET—The web application framework

  • Silverlight—A browser plugin for client-side web application programming

  • XNA—[3]The game programming system

  • Microsoft Robotics Kit—An environment for robot control and simulation

  • Volta—An experimental recompiler from Intermediate Language bytecode (IL) to JavaScript[4]

  • C# 4.0—The next version of C# and the CLR that will include dynamic features using the Dynamic Language Runtime (DLR)

IronPython is already being used in commercial systems, both to provide a scripting environment for programs written in other .NET languages and to create full applications. One great example called Resolver One,[5] a spreadsheet development environment, is how I (Michael) got involved with IronPython. You can see a screenshot of Resolver One in figure 1.1. At last count, there were over 40,000 lines of IronPython code in Resolver One, plus around 150,000 more in the test framework developed alongside it.

Resolver One: A full application written in IronPython

Figure 1.1. Resolver One: A full application written in IronPython

By the end of IronPython in Action, we hope you’ll have learned everything you need to tackle creating full applications with IronPython, integrating IronPython as part of another application, or just using it as another tool in your toolkit. You’ll also have explored some of these alternative programming techniques and used a variety of different aspects of the .NET framework. This exploration will enable you to make the best use of the Python language and the wealth of classes made available by .NET.

Before we can achieve any of this, an introduction is in order. This chapter introduces IronPython and the Python programming language. It explains why Python is a good fit for the .NET framework and will give you a tantalizing taste of what is possible with IronPython, via the interactive interpreter.

An introduction to IronPython

Python is a dynamic language that has been around since 1990 and has a thriving user community. Dynamic languages don’t require you to declare the type of your objects, and they allow you greater freedom to create new objects and modify existing ones at runtime. On top of this, the Python philosophy places great importance on readability, clarity, and expressiveness. Figure 1.2 is a slide from a presentation[6] by Guido van Rossum, the creator of Python; it explains why readability is so important in Python.

A slide from a presentation, emphasizing a guiding philosophy of Python

Figure 1.2. A slide from a presentation, emphasizing a guiding philosophy of Python

IronPython is an open source implementation of Python for .NET. It has been developed by Microsoft as part of making the CLR a better platform for dynamic languages. In the process, they’ve created a fantastic language and programming environment. But what exactly is IronPython?

What is IronPython?

IronPython primarily consists of the IronPython engine, along with a few other tools to make it convenient to use. The IronPython engine compiles Python code into IL, which runs on the CLR. Optionally IronPython can compile to assemblies, which can be saved to disk and used to make binary-only distributions of applications.

You can see how Python code is compiled and run by the IronPython engine in figure 1.3.

How Python code and the IronPython engine fit into the .NET world

Figure 1.3. How Python code and the IronPython engine fit into the .NET world

Figure 1.3 shows the state of IronPython version 1.[8] In April 2007, the IronPython team released an early version of IronPython 2, which introduces a radical new development, the Dynamic Language Runtime (DLR). The DLR is a hosting platform and dynamic type system taken out of IronPython 1 and turned into a system capable of running many different dynamic languages. You’ll be hearing more about the DLR in a short while.

Because Python is a highly dynamic language, the generated assemblies remain dependent on the IronPython dlls. Despite this, they’re still only compiled .NET code, so you can use classes from the .NET framework directly within your code without needing to do any type conversions yourself.

Accessing the .NET framework from IronPython code is extremely easy. As well as being a programming language in its own right, IronPython can be used for all the typical tasks you might approach with .NET, such as web development with ASP.NET (Active Server Pages, the .NET web application framework) or creating smart client applications with Windows Forms or WPF. As an added bonus, IronPython also runs on the version of the CLR shipped with Silverlight 2. You can use IronPython for writing client-side applications that run in a web browser, something that Python programmers have wanted for years!

IronPython itself is written in C# and is a full implementation of Python. IronPython 1 is Python version 2.4, whereas IronPython 2 is Python 2.5. If you’ve used Python before, IronPython is Python with none of the core language features missing or changed. Let’s make this clear: IronPython is Python.

Development cycles are typically fast with Python. With dynamically typed languages, tasks can be achieved with less code, making IronPython ideal for prototyping applications or scripting system administration tasks that you can’t afford to spend a lot of time on. Because of the readability and testability of well-written Python code, it scales well to writing large applications. You are likely to find that your prototypes or scripts can be refactored into full programs much more easily than writing from scratch in an alternative language.

If you’re already developing with .NET, you needn’t do without your favorite tools. Microsoft has incorporated IronPython support into Visual Studio 2005 through the Software Development Kit (SDK).[9] You can use Visual Studio to create IronPython projects with full access to the designer and debugger. Figure 1.4 shows Visual Studio being used to create a Windows application with IronPython.

Generated IronPython code in Visual Studio

Figure 1.4. Generated IronPython code in Visual Studio

Visual Studio 2008 integration exists in the form of IronPython Studio,[10] which is implemented through the Visual Studio Shell extensibility framework. IronPython Studio can either be run standalone (without requiring Visual Studio to be installed) or integrated into Visual Studio. It includes Windows Forms and WPF designers and is capable of producing binary executables from Python projects. Figure 1.5 shows IronPython Studio running in integrated mode as part of Visual Studio 2008.

Using the Windows Forms designer with IronPython Studio running in Visual Studio 2008

Figure 1.5. Using the Windows Forms designer with IronPython Studio running in Visual Studio 2008

An alternative version of .NET called Mono provides a C# compiler, runtime, and a large proportion of the framework for platforms other than Windows. IronPython runs fine on Mono, opening up the possibility of creating fully featured cross-platform programs using IronPython. Windows Forms is available on Mono, so GUI applications written with IronPython can run on any of the many platforms that Mono works on.

IronPython is a particularly interesting project for Microsoft to have undertaken. Not only have they taken a strong existing language and ported it to .NET, but they have chosen to release it with a sensible open source license. You have full access to IronPython’s source code, which is a good example of compiler design, and you can create derivative works and release them under a commercial license. This open approach is at least partly due to the man who initiated IronPython, Jim Hugunin. Let’s explore his role in creating IronPython, along with a brief history lesson.

A brief history of IronPython

The standard version of Python is often referred to as CPython, usually in the context of distinguishing it from other implementations; the C is because it’s written in C. CPython is overwhelmingly the most-used version of Python, and most Python code is written to run on it. CPython isn’t Python, though. Python is a programming language, and CPython is only one implementation (albeit an important one).[11]

IronPython isn’t the first version of Python to target an alternative platform to the usual Python runtime. The most famous alternative is Jython, Python for the Java Virtual Machine (JVM). The original version of Jython (or JPython, as it was known then) was created by a gentleman called Jim Hugunin.

Over the last few years, dynamic languages have been rising in popularity. Their emphasis on concise code and empowering the programmer have attracted a great deal of developer interest. But back in 2003, the CLR was widely regarded as being a bad platform for hosting dynamic languages.[12] Jim decided to write an article examining why .NET was so bad for these languages.

His experience with the JVM proved that it was certainly possible to create language runtimes capable of hosting both static and dynamic languages, and he wondered what Microsoft had gotten so wrong. Naturally he explored this by attempting a toy implementation of Python. To his horror, he discovered that, contrary to popular opinion, Python worked well on .NET. In fact, his initial attempt ran the basic Python benchmark pystone 1.7 times faster than CPython.

This outcome was unfortunate because a full language implementation is a major undertaking, and Jim now felt honor bound to take his experiment further.

After making his results public, Jim was invited to present them to Microsoft. Microsoft was particularly interested in the challenges and difficulties that Jim had encountered because they were keen to make the CLR a better platform for dynamic languages.

The upshot is that Jim joined the CLR team at Microsoft. A group of programmers were brought together to work on IronPython and, in the process, help improve the CLR. Importantly, Microsoft agreed to keep IronPython open source, with a straightforward license similar to the BSD[13] license.

Since the early releases, the Python community has been closely involved in the development of IronPython. Releases were made often, and Python programmers have been quick[14] to point out bugs in IronPython, or differences between IronPython and the way CPython behaves. The IronPython team was (and, in fact, still is) both fast and scrupulous in fixing bugs and incompatibilities between CPython and IronPython.

After many beta releases, IronPython 1.0 Production was released in September 2006. Meanwhile, other Microsoft teams were working to ensure that IronPython fit into the different members of the .NET family, including a Community Technology Preview (CTP) called IronPython for ASP.NET. IronPython for ASP.NET enables IronPython to be used for .NET web development, and introduces a change to the normal ASP model called no-compile pages.

Then in spring 2007, Microsoft surprised just about everyone with two important releases. The first was an alpha version of IronPython 2. IronPython 2 is built on top of an important component called the Dynamic Language Runtime (DLR).

The second surprise announcement, following hot on the heels of the DLR, was the release of Silverlight. Silverlight is a plugin that runs inside the browser for animation, video streaming, or creating rich-client web applications. The biggest surprise was that Silverlight 2 includes a cut-down version of .NET, called the CoreCLR, and the DLR can run on top of it. Any of the languages that use the DLR can be used for client-side web programming. The Python community in particular has long wanted a secure version of Python that they could use for client-side web programming. The last place they expected it to come from was Microsoft!

We’re hoping that you’re already convinced that IronPython is a great programming language; but, as a developer, why should you want to use IronPython? There are two types of programmers for whom IronPython is particularly relevant. The first is the large number of Python programmers who now have a new implementation of Python running on a platform different than the one they’re used to. The second type is .NET programmers, who might be interested in the possibilities of a dynamic language or perhaps need to embed a scripting engine into an existing application. We take a brief look at IronPython from both these perspectives, starting with Python programmers.

IronPython for Python programmers

As we’ve mentioned before, IronPython is a full implementation of Python. If you’ve already programmed with Python, there’s nothing to stop you from experimenting with IronPython immediately.

The important question is, why would a Python programmer be interested in using IronPython? The answer is twofold: the platform and the platform. We know that, initially, that might not make much sense, but bear with us. We’re referring first to the underlying platform that IronPython runs on—the CLR. Second, along with the runtime comes the whole .NET framework, a huge library of classes a bit like the Python standard library.

The CLR is an interesting platform for several reasons. The CLR has had an enormous amount of work to make it fast and efficient. Multithreaded programs can take full advantage of multiple processors, something that CPython programs can’t do because of a tricky creature called the GIL.[15] Because of the close integration of IronPython with the CLR, extending IronPython through C# code is significantly easier than extending CPython with C. There’s no C API to contend with; you can pass objects back and forth across the boundary without hassles and without reference counting[16] to worry about. On top of all this, .NET has a concept called AppDomains. AppDomains allow you to run code with reduced privileges, such as preventing it from accessing the filesystem, a feature that has long been missing from CPython.

Note

The ability to take advantage of multicore CPUs within a single process and the no-hassles bridge to C# are two of the major reasons that a Python programmer should be interested in IronPython. Chapter 14 shows how easy it is to extend IronPython from C#.

IronPython programs use .NET classes natively and seamlessly, and there are lots of classes. Two of the gems in the collection are Windows Forms and WPF, which are excellent libraries for building attractive and native-looking user interfaces. As a Python programmer, you may be surprised by how straightforward the programmer’s interface to these libraries feels. Whatever programming task you’re approaching, it’s likely that there’s some .NET assembly available to tackle it. As well as the standard libraries that come with the framework, there are also third-party libraries for sophisticated GUI components, such as data grids, that don’t have counterparts in CPython.

Table 1.1 shows a small selection of the libraries available to you in the .NET framework.

Table 1.1. Common .NET assemblies and namespaces

Assembly/namespace name

Purpose

System

Contains the base .NET types, exceptions, garbage collection classes, and much more.

System.Data

Classes for working with databases, both high and low level.

System.Drawing

Provides access to the GDI+ graphics system.

System.Management

Provides access to Windows management information and events (WMI), useful for system administration tasks.

System.Environment

Allows you to access and manipulate the current environment, like command-line arguments and environment variables.

System.Diagnostics

Tracing, debugging, event logging, and interacting with processes.

System.XML

For processing XML, including SOAP, XSL/T and more.

System.Web

The ASP.NET web development framework.

System.IO

Contains classes for working with paths, files, and directories. Includes classes to read and write to filesystems or data streams, synchronously or asynchronously.

Microsoft.Win32

Classes that wrap Win32 common dialogs and components including the registry.

System.Threading

Classes needed for multithreaded application development.

System.Text

Classes for working with strings (such as StringBuilder) and the Encoding classes that can convert text to and from bytes.

System.Windows.Forms

Provides a rich user interface for applications.

System.Windows

The base namespace for WPF, the new GUI framework that’s part of .NET 3.0.

System.ServiceModel

Contains classes, enumerations, and interfaces to build Windows Communication Foundation (WCF) service and client applications.

As we go through the book, we use several of the common .NET assemblies, including some of those new in .NET 3.0. More importantly, you’ll learn how to understand the MSDN documentation so that you’re equipped to use any assembly from IronPython. We also do some client-side web programming with Silverlight, scripting the browser with Python, something impossible before IronPython and Silverlight.

Most of the Python standard library works with IronPython; ensuring maximum compatibility is something the Microsoft team has put a lot of work into. But beware—not all of the standard library works; C extensions don’t work because IronPython isn’t written in C. In some cases, alternative wrappers may be available,[17] but parts of the standard library and some common third-party extensions don’t work yet. If you’re willing to swap out components with .NET equivalents or do some detective work to uncover the problems, it’s usually possible to port existing projects.

IronPython shines with new projects, particularly those that can leverage the power of the .NET platform. To take full advantage of IronPython, you’ll need to know about a few particular features. These include things that past experience with Python alone hasn’t prepared you for. Before we turn to using IronPython, let’s first look at how it fits in the world of the .NET framework.

IronPython for .NET programmers

IronPython is a completely new language available to .NET programmers. It opens up new styles of programming and brings the power and flexibility of dynamic programming languages to the .NET platform.

Programming techniques such as functional programming and creating classes and functions at runtime are possible with traditional .NET languages like VB.NET and C#, but they’re a lot easier with Python. You also get straightforward closures, duck typing, metaprogramming, and much more thrown in for free. We explore some of the features that make dynamic languages powerful later in the book.

IronPython is a full .NET language. Every feature of the .NET platform can be used, with the (current) exception of attributes for which you can use stub classes written in C#. All your existing knowledge of the .NET framework is relevant for use with IronPython.

So why would you want to use IronPython? Well, we can suggest a few reasons.

Without a compile phase, developing with IronPython can be a lot quicker than with traditional .NET languages; it typically requires less code and results in more readable code. A fast edit-run cycle makes IronPython ideal for prototyping and for use as a scripting language. Classes can be rewritten in C# at a later date (if necessary) with minimal changes to the programmer’s interface.

IronPython may be a new language, but Python isn’t. Python is a mature and stable language. The syntax and basic constructs have been worked out over years of programming experience. Python has a clear philosophy of making things as easy as possible for the programmer rather than for the compiler. Common concepts should be both simple and elegant to express, and the programmer should be left as much freedom as possible.

The best way to illustrate the difference between Python and a static language like C# is to show you. Table 1.2 demonstrates a simple Hello World program written in both C# and Python. A Hello class is created, and a SayHello method prints Hello World to the console. Differences (and similarities) between the two languages are obvious.

Table 1.2. Hello World compared in C# and IronPython

A small Hello World app in C#

Equivalent in Python

using System;

class Hello
{
  private string _msg;
  public Hello()
  {
    _msg = "Hello World";
  }
  public Hello(string msg)
  {
    _msg = msg;
  }
  public void SayHello()
  {
     Console.WriteLine(
        _msg);
  }
  public static void Main()
  {
    Hello app = new Hello();
    app.SayHello();
  }
}
class Hello(object):
  def __init__(self,
      msg='hello world'):
    self.msg = msg

    def SayHello(self):
        print self.msg

app = Hello ()
app.SayHello()

You can see from this example how much extra code is required in C# for the sake of the compiler. The curly braces, the semicolons, and the type declarations are all line noise and don’t add to the functionality of the program. They do serve to make the code harder to read.

This example mainly illustrates that Python is syntactically more concise than C#. It’s also semantically more concise, with language constructs that allow you to express complex ideas with a minimum of code. Generator expressions, multiple return values, tuple unpacking, decorators, and metaclasses are a few favorite language features that enhance Python expressivity. We explore Python itself in more depth in next chapter.

If you’re new to dynamic languages, the interactive interpreter will also be a pleasant surprise. Far from being a toy, the interactive interpreter is a fantastic tool for experimenting with classes and objects at the console. You can instantiate classes and explore their properties live, using introspection and the built-in dir and help commands to see what methods and attributes are available to you. As well as experimenting with objects, you can also try out language features to see how they work, and the interpreter makes a great calculator or alternative shell. You get a chance to play with the interactive interpreter at the end of this chapter.

If you’re looking to create a scripting API for an application, embedding IronPython is a great and ready-made solution. You can provide your users with a powerful and easy-to-learn scripting language that they may already know and that has an abundance of resources for those who want to learn. The IronPython engine and its API have been designed for embedding from the start, so it requires little work to integrate it into applications.

It’s time to take a closer look at Python the language and the different programming techniques it makes possible. We even reveal the unusual source of Python’s name.

Python on the CLR

The core of the .NET framework is the CLR. As well as being at the heart of .NET and Mono, it’s also now (in a slightly different form) part of the Silverlight runtime.

The CLR runs programs that have been compiled from source code into bytecode. Any language that can be compiled to IL can run on .NET. The predominant .NET languages, VB.NET and C#, are statically typed languages. Python is from a different class of language—it’s dynamically typed.

Let’s take a closer look at some of the things that dynamic languages have to offer programmers, including some of the language features that make Python a particularly interesting language to work with. We cover both Python the language and a new platform for dynamic languages: Silverlight. We start with what it means for a language to be dynamic.

Dynamic languages on .NET and the DLR

For a while, the CLR had the reputation of being a bad platform for dynamic languages. As Jim Hugunin proved with IronPython, this isn’t true. One of the reasons that Microsoft took on the IronPython project was to push the development of the CLR to make it an even better platform for hosting multiple languages, particularly dynamic languages. The DLR, which makes several dynamic languages available for .NET, is the concrete result of this work.

So, why all the fuss about dynamic languages?

First, dynamic languages are trendy; all the alpha-geeks are using them! Clearly, this isn’t enough of an explanation. Unfortunately, like many programming terms, dynamic is hard to pin down and define precisely. Typically, it applies to languages that are dynamically typed, that don’t need variable declarations, and where you can change the type of object a variable refers to.

More importantly, you can examine and modify objects at runtime. Concepts such as introspection and reflection, although not exclusive to dynamic languages, are very important and are simple to use. Classes, functions, and libraries (called modules in Python), are first-class objects that can easily be created in one part of your code and used elsewhere.

In statically typed languages, method calls are normally bound to the corresponding method at compile time. With Python, the methods are looked up (dynamically) at runtime, so modifying runtime behavior is much simpler. This is called late binding.

With static typing, you must declare the type of every object. Every path through your code that an object can follow must respect that type. If you deviate from this, the compiler will reject the program. In a situation where you may need to represent any of several different pieces of information, you may need to implement a custom class or provide alternative routes through your code that essentially duplicate the same logic.

In dynamic languages, objects still have a type. Python is a strongly typed language,[18] and you can only perform operations that make sense for that type. For example, you can’t add strings to numbers. The difference is that the Python interpreter doesn’t check types (or look up methods) until it needs to. Any name can reference an object of any type, and you can change the object that a variable points to. This is dynamic typing. Objects can easily follow the same path; you only differentiate on the type at the point where it’s relevant. One consequence of this is that container types (lists, dictionaries and tuples, plus user-defined containers in Python) can automatically be heterogeneous. They can hold objects of any type with no need for the added complexity of generics.

In many cases, the type doesn’t even matter, as long as the object supports the operation being performed; this is called duck typing.[19] Duck typing can remove the need for type checking and formal interfaces. For example, to make an object indexable as a dictionary-like container, you only need to implement a single method.[20]

All this can make programmers who are used to static type checking nervous. In statically typed languages, the compiler checks types at compile time, and will refuse to compile programs with type errors. This kind of type checking is impossible with dynamic languages,[21] so type errors can only be detected at runtime. Automated testing is more important with dynamic languages—which is convenient because they’re usually easier to test. Dynamic language programmers are often proponents of strong testing rather than static checking.[22]

Our experience is that type errors form the minority of programming errors and are usually the easiest to catch. A good test framework will greatly improve the quality of your code, whether you’re coding in Python or another language, and the benefits of using a dynamic language outweigh the costs.

Because types aren’t enforced at compile time the container types (in Python the list, tuple, set, and dictionary) are heterogeneous—they can contain objects of different types. This can make defining and using complex data structures trivially easy.

These factors make dynamic languages compelling for many programmers; but, before IronPython, they weren’t available for those using .NET. Microsoft has gone much further than implementing a single dynamic language, though. With IronPython, Jim and his team proved that .NET was a good environment for dynamic languages, and they created the entire infrastructure necessary for one specific language. In the DLR, they abstracted out of IronPython a lot of this infrastructure so that other languages could be implemented on top of it.

With the DLR it should be much easier to implement new dynamic languages for .NET, and even have those languages interoperate with other dynamic languages because they share a common type system. To prove the worth of the DLR, Microsoft has already created three languages that run on the DLR. The first of these is IronPython 2, followed by IronRuby, and Managed JScript. Table 1.3 lists the (current) languages that run on the DLR.

Table 1.3. Languages that run on the DLR

Language

Notes

IronPython 2

The latest version of IronPython. Built on top of the DLR.

IronRuby

A port of the Ruby language to run on .NET. Implemented by John Lam and team.

Managed JScript

An implementation of ECMA 3, otherwise known as JavaScript. Currently only available for Silverlight.

ToyScript[a]

A simple example language. Illustrates how to build languages with the DLR.

IronScheme[b]

An R6RS-compliant Scheme implementation based on the DLR.

Importantly, C# 4.0 will include dynamic features through the DLR.[23] This brings late binding and dynamic dispatch to C#, but will also make it easier to interact with dynamic languages from C#.

As an IronPython programmer, you needn’t even be aware of the DLR; it’s just an implementation detail of how IronPython 2 works. It does become relevant when you’re embedding IronPython into other applications.

Another important consequence of the DLR has to do with Silverlight, Microsoft’s new browser plugin.

Silverlight: a new CLR

At Mix 2007, a conference for web designers and developers, Microsoft surprised just about everyone by announcing both the DLR and Silverlight.

Silverlight is something of a breakthrough for Microsoft. Their usual pattern is to release an early version of a project with an exciting-sounding name, and then the final version with an anonymous and boring name.[24] This time around they’ve broken the mold; Silverlight was originally codenamed Windows Presentation Foundation Everywhere, or WPF/E. WPF is the new user interface library that’s part of .NET 3.0, and WPF/E takes it to the web.

What Silverlight really is, is a cross-platform and cross-browser[25] plugin for animation, video streaming, and rich web applications. The animation and video streaming features are aimed at designers who would otherwise be using Flash. What’s more exciting for developers is that Silverlight 2 comes with a version of the CLR called the CoreCLR. The CoreCLR is a cut-down .NET runtime containing (as the name implies) the core parts of the .NET framework. You can create web applications working with .NET classes that you’re already familiar with. It all runs in a sandboxed environment that’s safe for running in a browser.

Although Silverlight doesn’t work on Linux, Microsoft is cooperating with the Mono team to produce Moonlight,[26] which is an implementation of Silverlight based on Mono. It will initially run on Firefox on Linux, but eventually will support multiple browsers everywhere that Mono runs.

The best thing about Silverlight is that the DLR will run on it. So not only can you program Silverlight applications with C#, but you can also use any of the DLR languages, including IronPython. Silverlight is an exciting system. Rich interactive applications can be run in the browser, powered by the language of your choice. All of chapter 13 is devoted to Silverlight. As well as covering the basics of creating and packaging Silverlight applications, we walk through building a Silverlight Twitter client as an example.

Figure 1.6 shows one of the Silverlight samples[27] to illustrate the dynamic power of DLR languages running in Silverlight.

The Silverlight DLRConsole sample with a Python and Ruby Console

Figure 1.6. The Silverlight DLRConsole sample with a Python and Ruby Console

This console allows you to execute code with live objects and see the results in the canvas to the right. The console supports both IronRuby and IronPython, and you can switch between them live!

Three DLR languages currently available for use with Silverlight are IronPython, IronRuby, and Managed JScript. Managed JScript is an ECMA 3–compatible implementation of JavaScript, created by Microsoft to make it easier to port AJAX applications to run on Silverlight.

Another way of using Silverlight is particularly interesting. The whole browser Document Object Model (DOM)[28] is accessible, so we can interact with and change the HTML of web pages that host Silverlight. We can also interact with normal unmanaged JavaScript: calling into Silverlight code from JavaScript and vice versa. It’s already possible to write a client-side web application with the presentation layer in JavaScript, using any of the rich set of libraries available and the business logic written in IronPython.

It’s important to remember that, whether it runs in the browser or on the desktop, IronPython code is Python code. To understand IronPython and the place it has in the .NET world, you’ll need to understand Python. It’s time for an overview of the Python language.

The Python programming language

Python is a mature language with a thriving user community. It has traditionally been used mostly on Linux- and Unix-type platforms; but, with the predominance of Windows on the desktop, Python has also drawn quite a following in the Windows world. It’s fully open source; the source code is available from the main Python website and a myriad of mirrors. Python runs on all the major platforms, plus many more, including obscure ones such as embedded controllers, Windows Mobile, and the Symbian S60 platform used in Nokia.

Note

Python is an open source, high-level, cross-platform, dynamically typed, interpreted language.

Python was created by Guido van Rossum in 1990 while he worked for CWI in the Netherlands. It came out of his experience of creating a language called ABC, which had many features making it easy to use, but also some serious limitations. In creating Python, Guido aimed to create a new language with the good features from ABC, but without the limitations.

Python is now maintained by a core of developers, with contributions from many more individuals. Guido still leads the development and is known as the Benevolent Dictator for Life (BDFL), a title first bestowed during the discussions of founding a Python Software Association. Oh, and yes, Python was named after the Monty Python comedy crew.

Python itself is a combination of the runtime, called CPython, and a large collection of modules written in a combination of C and Python, collectively known as the standard library. The breadth and quality of the standard library has earned Python the reputation of being batteries included. The IronPython team has made an effort to ensure that as much of the standard library as possible still works. IronPython is doubly blessed with a full set of batteries from the .NET framework and a set of spares from the standard library.

One of the reasons for the rise in popularity of Python is the emphasis it places on clean and readable code. The greatest compliment for a Python programmer isn’t that his code is clever, but that it’s elegant. To get a quick overview of the guiding philosophy of Python, type import this at a Python console![29] You can see the result in figure 1.7.

The Zen of Python, as enshrined in the Python standard library

Figure 1.7. The Zen of Python, as enshrined in the Python standard library

Python is a multipurpose programming language used for all sorts of tasks. It’s possible you’ve already used applications or tools written in Python without even being aware of it. If you’ve used YouTube, Yahoo Maps, or Google, then you’ve been using tools built or supported behind the scenes with Python.

Python gets used for web development with web frameworks such as Zope, Django, and TurboGears. The BitTorrent application and SpamBayes (an Outlook plugin to combat spam) are both written in Python. Yum, the Linux package manager; Mnet, the distributed file store; Mailman, the GNU mailing list manager; and Trac, a popular project management and bug-tracking tool, are all written in Python. It’s used by companies including Google, NASA, Sony Imageworks, Seagate, and Industrial Light & Magic. It’s also used a great deal by the scientific community, particularly in bioinformatics and genomics.[30]

Because of the clarity of the syntax, Python is very easy to learn. Beginners can start with simple procedural-style programming and move into object-oriented programming as they understand the concepts, but other styles of programming are also supported by Python.

Multiple programming paradigms

Python is fundamentally an object-oriented[31] programming language. Everything you deal with is an object, but that doesn’t mean that you’re limited to the object-oriented programming style of programming in Python.

Procedural programming, the predecessor of object-oriented programming, is one alternative. Python doesn’t force you to create classes if you don’t want to. With the rich set of built-in datatypes and those available in the standard library, procedural programming is often appropriate for simple tasks. Because many people have past experience with procedural programming, it’s common for beginners to start here. Few can avoid the allure of object-oriented programming for long, though.

Functional programming is an important programming concept. Pure functional programming allows functions to have no side effects; it can be hard to understand, but the basic concepts are straightforward enough. In functional programming languages, Python included, functions are first-class objects. You can pass functions around, and they can be used far from where they’re created.

Because class and function creation is done at runtime rather than compile time, it’s easy to have functions that create new functions or classes—that is, function and class factories. These make heavy use of closures. Local variables used in the same scope a function is defined in can be used from inside the function. They’re said to have been captured by the function. This is known as lexical scoping.[32]

You can have parts of your code returning functions that depend on the local values where they were created. These functions can be applied to data supplied in another part of your code. Closures can also be used to populate some arguments of a function, but not all of them. A function can be wrapped inside another function with the populated arguments stored as local variables. The remaining arguments can be passed in at the point you call the wrapper function. This technique is called currying.

Metaprogramming is a style of programming that has been gaining popularity recently through languages like Python and Ruby. It’s normally considered an advanced topic, but it can be useful at times. Metaprogramming techniques allow you to customize what happens at class-creation time or when attributes of objects are accessed; you can customize all attribute access, not just individual attributes (through properties).

By now we’re sure you’re keen to use IronPython and see what it has to offer for yourself. In the next section, we look at the interactive interpreter, and you get the chance to try some Python code that uses .NET classes. Some basic .NET terms are explained as we go. It’s fairly straightforward, but we don’t give a blow-by-blow account of all the examples; explanations will come soon.

Live objects on the console: the interactive interpreter

Traditional Python (boy, does that make me feel old) is an interpreted language. The source code, in a high-level bytecode form, is evaluated and executed at runtime. Features such as dynamic object lookup and creating and modifying objects at runtime fit in well with this model. The CLR also runs bytecode, but its bytecode is optimized to work with a powerful just-in-time compiler and so .NET languages tend to be called compiled languages.

Something else that fits in well with dynamically evaluated code is an interactive interpreter, which allows you to enter and execute individual lines (and blocks) of code. By now, you should have a good overview of what IronPython is; but, to really get a feel for it, you need to use it. The interactive interpreter gives you a chance to try some Python code. We use some .NET classes directly from Python code. This is both an example of IronPython in action and a demonstration of the capabilities of the interactive interpreter.

Using the interactive interpreter

When you download IronPython,[33] you have two choices. You can download and install the msi installer (IronPython 2 only), which includes the Python 2.5 standard library. Alternately, you can download and unpack the binary distribution that comes as a zip file. Whichever route you take, you’ll have two executables, ipy.exe and ipyw.exe, which are the equivalents of the Python executables python.exe and pythonw.exe. Both are used to launch Python scripts; ipy.exe launches them with a console window, and ipyw.exe launches programs as Windows applications (without a console).

ipy.exe path_topython_script.py

If you run ipy.exe on its own, it starts an interactive interpreter session. The IronPython interpreter supports tab completion and coloring of the output, both of which are useful. The command line options to enable these are

ipy -D -X:TabCompletion -X:ColorfulConsole

You should see something like figure 1.8.

The IronPython interactive interpreter

Figure 1.8. The IronPython interactive interpreter

IronPython is dependent on the .NET framework 2.0.[34] The interpreter, and any applications created with IronPython, will only run on computers with .NET 2.0 (or Mono) installed. In recent days, Microsoft has been pushing .NET 2.0 out to Windows machines via Windows update. A high proportion of Windows machines will already have .NET 2.0 installed. Windows machine that aren’t .NET equipped will require at least the redistributable dotnetfx.exe.[35]

The interactive interpreter allows you to execute Python statements and see the results. This is known as a ‘read-eval-print’ loop (REPL).[36] It can be extremely useful for exploring objects, trying out language features, or even performing quick one-off operations.

If you enter an expression, the resulting value will be printed to the console. The result of the last expression, whether value or object, is available in the interpreter by using the underscore (_). If you can’t find a calculator, then you can always turn to the Python interpreter instead.

Tip

Code examples to be typed into an interactive interpreter session start each line that you enter with >>> or .... This is the interpreter prompt and reflects the actual appearance of the session. It’s a common convention when presenting Python examples.

>>> 1.2 * (64 / 2.4) + 36 +2 ** 5
100.0
>>> _
100.0
>>> x = _
>>> print x
100.0

More importantly, blocks of code can be entered into the interpreter, using indentation in the normal Python manner.

>>> def CheckNumberType(someNumber):
...   if type(someNumber) == int:
...      print 'Yup, that was an integer'
...   else:
...      numType = type(someNumber)
...      print 'Nope, not an integer: %s' % numType
...
>>> CheckNumberType(2.3)
Nope, not an integer: <type 'float'>
>>> type(CheckNumberType)
<type 'function'>

We’re not going to get very far in this book without building an understanding of .NET terminology. Before demonstrating some more practical uses of the interpreter, we’ll look at some basic .NET concepts.

The .NET framework: assemblies, namespaces, and references

Assemblies are compiled code (in the form of dlls or exe files)—the substance of a .NET application. Assemblies contain the classes used throughout an application.

The types in an assembly are contained in namespaces. If there are no explicitly defined namespaces, they’re contained in the default namespace. Assemblies and namespaces can be spread over multiple physical files, and an assembly can contain multiple namespaces. Assemblies and namespaces are roughly the same as packages and modules in Python, but aren’t directly equivalent.

For a program to use a .NET assembly, it must have a reference to the assembly. This must be explicitly added. To add references to .NET assemblies, you use the clr module. In Python, the term module has a different meaning than the rarely used .NET module. To use clr, you have to import it, and then you can call AddReference with the name of the assembly you want to use.

After adding a reference to the assembly, you’re then free to import names[37] from namespaces it contains into your IronPython program and use them.

>>> import clr
>>> clr.AddReference('System.Drawing')
>>> from System.Drawing import Color, Point
>>> Point(10, 30)
<System.Drawing.Point object at 0x0...2B [{X=10,Y=30}]>
>>> Color.Red
<System.Drawing.Color object at 0x0...2C [Color [Red]]>

There are a few exceptions. The IronPython engine already has a reference to the assemblies it uses, such as System and mscorlib. There’s no need to add explicit references to these.

The clr module includes more goodies. It has different ways of adding references to assemblies, including specifying precisely which version you require. We take a more detailed look at some of these later in the book. For now, we demonstrate how to use live objects from the interactive interpreter.

Live objects and the interactive interpreter

The interactive interpreter is shown off at its best when it’s used with live classes. To illustrate this, here’s some example code using Windows Forms. It uses the System.Windows.Forms and System.Drawing assemblies.

Live objects and the interactive interpreter

So now you should’ve created a form with the title Hello World. Because you haven’t yet started the application loop, there’s no guarantee that it will be visible. Even if it is visible, it will be unresponsive, as you can see in figure 1.9.

A Hello World form, shown before the event loop is started

Figure 1.9. A Hello World form, shown before the event loop is started

A Hello World form, shown before the event loop is started

When the application event loop is started and the form is shown, the form will look like figure 1.10. Every time you click the button, it will move diagonally across the form.

Active Hello World form with a button

Figure 1.10. Active Hello World form with a button

We cover all the details of what is going on here later; the important thing to note is that the whole process was done live.

If you run this demonstration, you’ll notice that when you execute the Application.Run(form) command, the console loses control. Control doesn’t return to the console until you exit the form because starting the application loop takes over the thread it happens on.

As well as enabling you to work with live objects, Python has powerful introspective capabilities. A couple of convenience commands for using introspection are particularly effective in the interpreter.

Object introspection with dir and help

It’s possible when programming to occasionally forget what properties and methods are available on an object. The interpreter is a great place to try things out, and two commands are particularly useful.

dir(object) will give you a list of all the attributes available on an object. It returns a list of strings, so you can filter it or do anything else you might do with a list. The following code snippet looks for all the interfaces in the System.Collections namespace by building a list and then printing all the members whose name begins with I.

>>> import System.Collections
>>> interfaces = [entry for entry in dir(System.Collections)
... if entry.startswith('I')]
>>> for entry in interfaces:
...   print entry
...
ICollection
IComparer
IDictionary
IDictionaryEnumerator
IEnumerable
IEnumerator
IEqualityComparer
IHashCodeProvider
IList
>>>

The next command is help. help is a built-in function for providing information on objects and methods. It can tell you the arguments that methods take; for .NET methods, it can tell you what types of objects the arguments need to be. Sometimes the result contains other useful information.

As an example, let’s use help to look at the Push method of System.Collections.Stack.

>>> from System.Collections import Stack
>>> help(Stack.Push)
Help on method-descriptor Push
 | Push(...)
 |    Push(self, object obj)
 |
 |     Inserts an object at the top of the
 |      System.Collections.Stack.
 |
 |     obj: The System.Object to push onto the
 |      System.Collections.Stack. The value can be null.

help will also display docstrings defined on Python objects. Docstrings are strings that appear inline with modules, functions, classes, and methods to explain the purpose of the object. Many members of the Python standard library have useful docstrings defined. If you use help on the makedirs function from the os module, you get the following:

>>> import os
>>> help(os.makedirs)
Help on function makedirs in module os
 | makedirs(name, mode)
 |    makedirs(path [, mode=0777])
 |
 |       Super-mkdir; create a leaf directory and all intermediate ones.
 |       Works like mkdir, except that any intermediate path segment (not
 |       just the rightmost) will be created if it does not exist.  This is
 |       recursive.
 |

The interactive interpreter is an extremely useful environment for exploring .NET assemblies. You can import objects and construct them live to explore how they work. It’s also useful for one-off jobs such as transforming data. You can pull the data in, push it back out again, and walk away.[38]

Summary

You’ve seen that Python is a flexible and powerful language suitable to a range of tasks. IronPython is a faithful implementation of Python for the .NET platform, which itself is no slouch when it comes to power and features. Whether you’re interested in writing full applications, tackling scripting tasks, or embedding a scripting language into another application, IronPython has something to offer you.

Through the course of this book, we demonstrate these different practical uses of IronPython. There are also sections that provide reference matter for the hard work of turning ideas into reality when it comes to real code.

The interactive interpreter is important for experimentation. It’s a great tool for trying things out, reminding you of syntax or language features, and for examining the properties of objects. The dir and help commands illustrate the ease of introspection with Python, and we expect that, as you work through more complex examples, they’ll be helpful companions on the journey.

In the last section, you got your feet wet with Python; but, before you can do anything useful with it, you’ll need to learn a bit more of the language. The next chapter is a fast-paced tutorial that will lay the foundations for the examples built in the rest of the book.



[1] Microsoft’s next generation user interface framework.

[2] In the C++/CLI flavor, which is sometimes still referred to by the name of its predecessor, Managed C++. Use of C# and VB.NET is more widespread for .NET programming.

[3] XNA is a recursive acronym standing for XNA’s Not Acronymed.

[4] Allowing you to write client-side code for web applications in Python and have it recompiled to JavaScript for you.

[7] .NET does provide ways to access unmanaged code contained in traditional compiled dlls.

[8] And as a simplified view, it’s true of IronPython 2 as well, except the IronPython engine is comprised of the Dynamic Language Runtime and IronPython-specific assemblies.

[9] The Visual Studio SDK is a Microsoft extension that includes IronPython support.

[11] Python has no formal specification. It’s defined by the language reference documentation and from CPython, which is called a reference implementation.

[12] For example, see the InfoWorld article from 2004, “Does .Net have a dynamic-language deficiency?” at http://www.infoworld.com/article/04/02/27/09FEmsnetdynamic_1.html. Ironically, this was written by Jon Udell, who now works for Microsoft.

[13] The BSD license is a popular (and permissive) open source license that originated with the Berkeley Software Distribution, a Unix-like operating system.

[14] At least perhaps partly because of suspicions about Microsoft’s intentions for Python...

[15] The Global Interpreter Lock, which makes some aspects of programming with Python easier but has this significant drawback.

[16] CPython uses reference counting for garbage collection, which extension programmers have to take into account.

[17] Several of these are provided by FePy, a community distribution of IronPython. See http://fepy.sourceforge.net/

[18] Some dynamic languages are weakly typed and allow you to do some very odd things with objects of different types.

[19] If the object walks like a duck and quacks like a duck, let’s treat it like a duck...

[20] That method is called __getitem__ and is used for both the mapping and sequence protocols in Python.

[21] Although not all statically typed languages require type declarations. Haskell is a statically typed language that uses type inferencing instead of type declarations. ShedSkin is a Python to C++ compiler that also uses type inferencing and compiles a static subset of the Python language into C++. C# 3.0 gained an extremely limited form of type inferencing with the introduction of the var keyword.

[22] A phrase borrowed from Bruce Eckel, a strong enthusiast of dynamic languages in general and Python in particular. See http://www.mindview.net/WebLog/log-0025.

[23] These features were debuted at the 2008 PDC conference by Anders Hejilsburg. See http://channel9.msdn.com/pdc2008/TL16/.

[24] Take Avalon, for example, which became WPF.

[25] Although Microsoft’s idea of cross-platform is Mac OS X and Windows and their idea of cross-browser is Safari, IE, and Firefox, they’ve said that Opera support is in the works.

[27] The DLRConsole can be downloaded as one of the samples from the Silverlight Dynamic Languages SDK at http://www.codeplex.com/sdlsdk.

[28] A system that exposes a web page as a tree of objects.

[29] The console will need the Python standard library on its path.

[30] Particularly because of the simplicity and power of Python’s string handling, which is ideal for slicing and splicing gene sequences.

[31] For a good introduction to object-oriented programming with Python, see http://www.voidspace.org.uk/python/articles/OOP.shtml.

[33] From the IronPython website on CodePlex: http://www.codeplex.com/IronPython.

[34] IronPython 2 requires .NET 2.0 Service Pack 1.

[36] From the first appearance of an interactive interpreter with the Lisp language.

[37] The imported names are names that refer to objects. These will usually be classes when importing from a .NET namespace. You’ll learn more about Python imports in chapter 2.

[38] This is a quote from Python expert Tim Golden who does a lot of work with databases and Python, some of it using only the interactive interpreter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.251.169