Blograby

Working with Existing Objects

In many respects, most of what you work with in IronPython is some sort of object. When working with most languages, you have a vision of data types as being just that — data only. You assign a number to a variable and see that the variable has some kind of presence on the stack as simply a number. However, in IronPython, a variable holding a number is a lot more than simply a number — the variable is actually an object with callable methods and properties that tell you more about the variable. For example, try assigning a number to a variable (say i in this case), and then call i.__sizeof__(). You’ll discover that you get back the size of the variable in memory. With this bit of information in mind, it’s time to discover what other objects lurk beneath the surface of the supposed simplicity that IronPython provides. The following sections tell you more about the existing objects in IronPython.

Discovering IronPython Objects

IronPython objects are everywhere, just waiting for you to discover them. Let’s take a closer look at the number example in the introduction to this section. Go ahead and open a copy of the IronPython interpreter, type int = 5, and press Enter. Now type dir(int) and press Enter. That’s right, you can treat int as an object in IronPython. You’ll see the information shown in Figure 5-1. All these methods and properties apply to int because int is an object, not just a variable as you might suppose when using other languages.

Figure 5-1: Objects lurk everywhere in IronPython.

In fact, you may have noticed in previous chapters that it appears that everything in IronPython is an object. It’s true; everything you use in IronPython is an object, so always remember to use the dir() function to display the things you can do with the objects you use. The following sections describe a few of the more common IronPython objects and how to work with them. Don’t worry — you’ll see a lot more objects before you complete the book. These sections are simply here to whet your appetite for more objects later.

Working with String Objects

Strings are one of the first objects many people use. You write that first “Hello World” application and marvel when the words appear on screen. In fact, strings are the mainstay of many applications. Without strings you can’t provide prompts to the user or ask for input. Sure, you may not do any heavy lifting with strings, but every application out there requires strings to work properly. The following sections discuss the IronPython string object in more detail.

Performing Standard Tasks with Strings

You’ve already seen a few of the things you can do with strings in previous chapters. This chapter takes a little more organized look at the methods and properties associated with strings. The following list provides an overview of the most common tasks you can perform.

Formatting String Output

String formatting can become quite complex in Python and IronPython. However, if you start with the basics, you’ll find that you can usually figure out the complex elements without too much trouble. A basic format string contains one or more fields. A field is simply some text that appears within curly braces that you replace with a value. In fact, if you’ve worked with any .NET language, you’ve already used fields. Here’s a simple sentence that contains a field.

[code]

MyString = ‘Hello {0}‘

[/code]

Of course, you won’t want to print this string directly onscreen. Instead, you’ll want to replace {0} with some other value. In order to do this, you can use the format() method as shown here.

[code]

MyString.format(‘George’)

[/code]

The interpreter replaces the {0} with the name George. Consequently, you see ‘Hello George’ as output from these two lines of code. You have a number of options when working with replaceable variables in a string. The following list shows just a few of the options:

A formatting string can contain as many variables as needed to provide complete information to the user. For example, you can add a second argument like this.

[code]

MyString = ‘Hello {0} from {1}‘

[/code]

When you call the format() method, you now need to add some more information. The format() method input for this string might look like this.

[code]

MyString.format(‘George’, ‘London’)

[/code]

In many cases, you need to provide input that doesn’t translate into a string. For example, you might need to provide integer input for some strings. The interpreter won’t automatically perform a conversion in this case so you need to perform the task manually. The conversion symbol is the exclamation mark (!) and the most common conversion is string (s). You can also call the repr() conversion function by using r in place of s. Here’s an example of a conversion:

[code]

MyString = ‘{0!s} + {1!s} = {2!s}‘
MyString.format(1, 2, 1+2)

[/code]

In this case, you get an output of ‘1 + 2 = 3’. Notice that this example places the math directly in the format string. You could place the output of a function there as well.

So far, the examples haven’t done much formatting — they have simply replaced field values with information found in other sources. The format operator is the colon (:) and you can combine it with the conversion operator if you want. To see how this works, think about displaying the previous example in hexadecimal format. In that case, your code might look like this:

[code]

MyString = ‘{0:X} + {1:X} = {2:X}‘
MyString.format(10, 20, 10+20)

[/code]

The output from this code is in hexadecimal format — you’d see ‘A + 14 = 1E’. Of course, you might want all the values to take up the same space. In this case, you can tell the interpreter to add some space to the output using the following string:

[code]

MyString = ‘{0:0=4X} + {1:0=4X} = {2:0=4X}‘

[/code]

This string outputs numbers with zeros as padding. The padding appears after any sign information. In addition, each of the entries is four digits long. Consequently, the output now looks like this: ‘000A + 0014 = 001E’. The formatting has specific entries, all of which are options. It looks like this:

[code]

[[fill]align][sign][#][0][width][.precision][type]

[/code]

Fill characters determine what appears as part of the padding the interpreter uses when you specify a width, and the field value doesn’t fill the entire space. The default padding is the space, but you can specify any character other than the closing brace, which would end the formatting definition. When you specify a fill character, such as the 0 used in the previous example, you must also use one of the alignment characters found in Table 5-1.

Table 5-1: String Formatting Alignment Options

The use of signs in the output comes next. For example, you can choose to have all positive numbers begin with a plus sign (+) so there’s no confusion about their positive value. Table 5-2 shows the sign formatting options you can use.

Table 5-2: String Formatting Sign Options

The pound sign (#), which is called by a host of names, such as octothorp and number sign, tells the interpreter to add a letter after numeric values to show their base — b for binary, o for octal, or x for hexadecimal (decimal values never have the letter added). For example, if you change the previous formatting string to include the # like this:

[code]

MyString = ‘{0:0=#6X} + {1:0=#6X} = {2:0=#6X}‘

[/code]

the output changes to include the correct base designation. You’ll see ‘0X000A + 0X0014 = 0X001E’ as the output.

The width and precision entries come next. If you precede the width value with a 0, then the interpreter will pad the numeric values with zeros. The precision entry tells the interpreter how many decimal places to use for the output.

The final formatting you can request is the output type. In this case, you must decide in advance what kind of value that the field will accept — integers use different type designations than floating point and decimal types. Table 5-3 shows the types you can use for integer input, while Table 5-4 shows the types for floating point and decimal.

Table 5-3: Integer Formatting Types
Table 5-3: Integer Formatting Types (continued)
Table 5-4: Floating Point and Decimal Formatting Types

Working with Numeric Objects

Numeric objects include a number of methods that make working with them easier. It’s important to realize that some of the methods that apply to strings also apply to numbers. For example, you can access the __format__() method when working with a number. In addition, you can easily turn a number into a string using the __str__() method. Some string-oriented methods actually revolve around numbers, such as the format typing described in Tables 5-3 and 5-4. In short, don’t think that numbers are limited to number-specific methods. The following sections consider the kinds of things you can do with numbers.

Considering Numeric Type Differences

IronPython generally splits numbers between integers and floats (decimals are included with floats). The two numeric presentations are handled differently by the interpreter and even have different representations at the hardware level, so it’s no surprise that there are differences you must consider when working with a number. However, as when working with strings, you can cause numbers to cross the divide. An integer can appear as a float using the __float__() method. Likewise, you can use __int__() or __trunc__() methods.

Numeric types have some similarities. For example, both integers and floats support the __abs__() method, which returns the absolute value of the number. In some cases, you have to look for the similarities. For example, floats provide a hex() method that performs the same task as __hex__() does for integers.

Integers have a few interesting methods that floats can’t support because of their memory representation. For example, you can use the __and__() method to “and” the value of the variable with another integer (where “anding” 5 and 4 would result in an output of 4, and “anding” 5 and 7 would result in an output of 5). In fact, here’s a list of methods that appear for integers that don’t appear for floats (you’ll notice that most of them have something to do with bit-level manipulation):

Floats, likewise, have a few methods that apply only to them. Most of these methods deal with performing comparisons. For example, you need a special method to determine that two floats are equal to each other (the __eq__() method). The following list shows these methods:

Performing Standard Tasks with Numbers

Now that you have a better idea of how numbers compare, it’s time to look at some specific methods. This section describes some of the more common methods used with numbers. You’ll see a good many of the other methods demonstrated as the book progresses.

Working with Boolean Objects

Boolean objects provide access to truth values about other objects and their relationships. Many objects have Boolean methods built in. For example, when working with a float, you can use the equality methods __eq__(), __ge__(), __gt__(), __le__(), __lt__(), and __ne__() to determine relationships between values. In fact, Boolean objects also include these equality methods and you might find them useful at times for comparing the truth value of two Boolean objects.

For the most part, Boolean objects have little in the way of other methods that you need when creating a typical IronPython application. For example, you could use the __long__() method to convert the Boolean to long integer, but that really wouldn’t accomplish much for most developers.

 


 

Exit mobile version