Chapter 9. Built-In Functions

CONTENTS
  •  Conversion
  •  Namespace: dir(), globals(), locals(), vars()
  •  Type Checking: callable(), type()
  •  Operations
  •  Advanced Topic: Functional Programming
  •  Advanced exec and eval
  •  Summary

Terms in This Chapter

  • Built-in (intrinsic) function

  • Bytecode

  • Collection

  • eval statement

  • exec statement

  • Functional programming

  • Hashtable

  • Hash value

  • Hierarchy

  • Identity operator

  • is operator

  • Keyword

  • Lambda function

  • Mutable/Immutable

  • Namespace

  • Name/value pair

  • Octal

  • Parameter

  • Sequence

A good part of the simplicity and elegance of Python comes from its built-in (or instrinsic) functions. Many of these are longhand for other operators for example, the cmp() function, which performs the ==, =>, =<, <, > operations, and the repr() function, which back-quotes an object. When there's no equivalent operator, the built-in function is often referred to simply as an "operator."

Generally, Python built-in functions are equivalent to keywords in other languages. One example is C++'s keyword sizeof(), which determines the size of an array or other structure; its Python counterpart is len(), which determines the length of a sequence. Similarly, Java's instanceof() is equivalent to Python's isinstance().

Conversion

Sooner or later you're going to need to convert from one type to another. You may be reading in strings from files and want to convert them to text, or, before writing numbers to a text file, you may want to convert them to strings. Python has several built-in functions to do this.

Converting Numbers to Strings: chr(), str(), hex(), oct()

The chr() function converts a number to a character. Remember that there are no characters in Python, so chr() returns a single character in a string.

>>> chr(97) 'a' >>> chr(122) 'z'

It may seem that you would rarely use chr(), but wait until Chapter 12, when it will come in handy for converting a Java binary array into a Python string.

The str() function converts any object, including numeric types, into a string. (Remember, unlike other languages Python treats all types as objects.)

>>> str(1) '1'

The hex() function converts a number into its hexadecimal equivalent.

>>> hex(255) '0xff' >>> hex(1l) '0x1L'

Hexadecimal is a base 16 numbering system used in many computers that allows you to display a byte with two digits. We'll see it again when we cover the Java InputStream in Chapter 12.

The oct() function converts a number into its octal equivalent. Octal is a base 8 numbering system.

>>> oct(1) '01' >>> oct(9) '011'

oct() and hex() work only with integers and longs. They don't work with floats.

You probably won't use chr(), oct(), or hex() very much, if at all, but str() you'll use a great deal.

Converting Strings to Numbers: float(), int(), long(), ord()

The float() function converts a string to a float.

>>> f = float("1.1") >>> type(f) <jclass org.python.core.PyFloat at 1662336> >>>

The int() function converts strings to integers.

>>> str = "1" >>> num = int(str) >>> type(num) <jclass org.python.core.PyInteger at 3414368> >>>

The long() function converts a string into a long.

>>> long("12345678901234567890") 12345678901234567890L

The ord() function converts a character (that is, a string with one element) into its ASCII value.

>>> ord("A"), ord("Z") (65, 90) >>>

Converting Numbers to Different Numeric Types: coerce()

The coerce() function converts one numeric type into another, or rather it changes the type of one value to another type. Actually, coerce() doesn't change the value but returns it in a tuple.

Declare some variables to convert.

>>> myinteger = 1          # an int >>> mylong = 1l            # a long >>> myfloat = 1.0          # a float >>> mystring = "1"  # a non-numeric object

Coerce an integer into a long.

>>> coerce(mylong, myinteger) (1L, 1L)

Do the same as above, but swap the position of the integer and the long.

>>> coerce(myint, mylong) (1L, 1L)

Coerce an integer into a float.

>>> coerce(myint, myfloat) (1.0, 1.0)

Coerce a long into a float. (The long has to be in the range of allowable values for the Float type.)

>>> coerce(mylong, myfloat) (1.0, 1.0)

coerce() works only with numeric types. It won't work with strings, as you can see here:

>>> coerce(mystring, myint) Traceback (innermost last):   File "<interactive input>", line 0, in ? TypeError: number coercion failed >>>

To convert an integer or a long into a float, do this:

>>> myint = 10 >>> myint = coerce(1.0, 10)[1] >>> print myint 10.0

Converting Sequences: list(), tuple()

Remember that tuples are immutable, which means that you can't add items to them. If you need to add items to a sequence, you have to use a list. Conversely, you can't use a list as a key into a dictionary. Since dictionaries store items based on a hashtable that uses the hash value of the key, they need types that won't change that is, immutable tuples. Python has two built in functions to deal with these problems.

The list() function converts an immutable sequence (such as a tuple) into a mutable one (such as a list). Here's an example.

Create a tuple.

>>> tup = (1,2,3,4,5,6,7,8,9)

Try to add something to it (you'll fail).

>>> tup.append(1) Traceback (innermost last):   File "<stdin>", line 1, in ? AttributeError: 'tuple' object has no attribute 'append'

Convert the tuple, tup, into a list, ls.

>>> ls =list(tup) >>> ls.append(10)

The tuple() function converts a mutable sequence into a tuple. We'll continue our last example to demonstrate how it works.

Convert ls to a tuple, tup, and display it.

>>> tup=tuple(ls) >>> tup (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) >>>

tuple() and list()

The tuple() and list() functions take any kind of sequence. Here's what happens if you pass tuple() a tuple:

>>> tup = (1,2,3) >>> id(tup), id(tuple(tup)) (201160, 201160) >>> tup is tuple(tup) 1

As you can see, the id of tup and the id of the tuple returned from tuple() are the same. We can demonstrate this with the identity operator, which returns as a true statement that tup is tuple(tup).

If you pass a list to tuple(), you get a new tuple.

>>> lst = [1,2,3] >>> id(lst), tuple(lst) (332828, (1, 2, 3)) >>> id(lst), id(tuple(lst)) (332828, 321564) >>> lst is tuple(lst) 0

Notice that, every time you call list(ls), you get a new copy of ls.

Converting Objects to Strings: str(), repr()

The str() function converts all object types to strings. The repr() function converts all object types to strings that might be able to reconstruct the object with a call to eval. Here's an example of both.

Create a list, a tuple, a string, and an integer object.

>>> list, tuple, string, int = [1,2],(1,2),"12",12

Create a dictionary object that contains the list, tuple, string and integer objects just created.

>>> dict ={"list":list, "tuple":tuple, "string":string, "int":12}

Show the string representation of the dictionary object.

>>> str(dict) "{'tuple': (1, 2), 'string': '12', 'list': [1, 2], 'int': 12} "

Show the repr() string representation of the dictionary object.

>>> repr(dict) "{'tuple': (1, 2), 'string': '12', 'list': [1, 2], 'int': 12} "

Namespace: dir(), globals(), locals(), vars()

In most languages, the namespace is decided at compile time, and there is no way to determine which variables are in it unless you try to use them and the program doesn't compile. With Python, you can see the variables in the namespace, and you can see what variables a given object exposes.

dir()

dir([object]) returns a list of namespace variables. If no arguments are passed, it returns a list of names in the current namespace; otherwise, it returns a list of an object's attribute names.

Here are two examples of dir() showing what's in the current namespace in a function and in a module, respectively:

>>> var1, var2, var3, var4 = 1,2,3,4 >>> dir() ['__builtins__', 'var1', 'var2', 'var3', 'var4'] >>> def func(lvar1, lvar2,lvar3,lvar4): ...    return dir() ... >>> func(var1,var2,var3,var4) ['lvar1', 'lvar2', 'lvar3', 'lvar4'] >>>

Here's an example showing dir() inspecting a module and a class.

Inspect the attributes of the sys module.

>>> import sys >>> dir(sys) ['__doc__', '__name__', '__stderr__', '__stdin__', '__stdout__', 'argv', 'builtin_module_names', 'copyright', 'dllhandle', 'exc_info', 'exc_type', 'exec_prefix', 'executable', 'exit', 'getrefcount', 'maxint', 'modules', 'path', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'settrace', 'stderr', 'stdin', 'stdout', 'version', 'winver']

Inspect the Exception class.

>>> dir(Exception) ['__doc__', '__getitem__', '__init__', '__module__', '__str__'] >>> type (Exception) #just to show that it is a class <jclass org.python.core.PyClass at 4958626>

Inspect an instance of the Exception class.

>>> e = Exception() >>> dir (e) ['args']

globals()

With a few exceptions, the globals() function is similar to dir(). It always returns the variable names defined in the current module, and it returns a dictionary where the name in the name/value pairs is the name of the object (the variable name) and the value is the object itself (the value). Even if you call globals() in a function call, it returns the global variables for that module.

>>> gvar1,gvar2,gvar3=1,"two",[3,3,3] >>> def func(): ...   return globals() ... >>> func() {'func': <function func at 428fc>, 'gvar3': [3, 3, 3], 'gvar1': 1, 'gvar2': 'two', '__builtins__': {'cmp': <built-in function cmp>, 'dir': <built-in function dir>, 'round': <built-in function round>, 'AttributeError': <class exceptions.AttributeError at 280e8>, 'SystemExit': <class exceptions.SystemExit at 28bd0>, 'str': <built-in function str>, 'ArithmeticError': ...

locals()

The locals() function is like globals() except that it returns the variables in the innermost namespace.

>>> def func2(var1, var2, var3): ...   return locals() ... >>> func2(1,2,3) {'var2': 2, 'var3': 3, 'var1': 1}

This shows the use of locals() in the body of func2 to print out the variables in func2's namespace.

locals() also returns any variables defined inside the function.

...   var4 = "more" ...   var5 = "five" ...   return locals() ... >>> func3(1,2,3) {'var2': 2, 'var3': 3, 'var1': 1, 'var4': 'more', 'var5': 'five'}

Here var4 and var5 are returned as well as the arguments passed to func3.

vars()

The vars() function is like locals() except that you can use it for any object type to list the object's public attributes. Here we use vars() to list the attributes in the Exception class. (Exception is always well, almost always in the namespace.)

>>> vars(Exception) {'__module__': 'exceptions', '__init__': <function __init__ at 27b8c>, '__doc__': None, '__str__': <function __str__ at 27be0>, '__getitem__': <function __getitem__ at 24d58>}

Type Checking: callable(), type()

The callable(object) function returns true if the object can be called like a function. Since more than object types can be callable (lambdas, functions, methods, class instances, etc.), this feature is very useful. Here's an example:

>>> callable(dir) 1

This is nice, but how do you use it? Let's say that you want to find out which objects in the current module are callable.

Define a class whose instances are callable.

>>> class myclass: ...   def __call__(self): ...          return "hello" ...

Define an instance of the callable class.

>>> hello = myclass()

Define some not so useful functions.

>>> def func():pass ... >>> def func1():pass ... >>> def func2():pass ... >>> def func3():pass

Iterate through the list of variables in the module namespace, and see which objects are callable.

>>> for (name,value) in vars().items(): ...   if (callable(value)): ...          print name + " is callable" ... hello is callable myclass is callable func is callable func1 is callable func2 is callable func3 is callable

The type() function returns the type of the object.

>>> type(myclass) <jclass org.python.core.PyClass . . .> >>> type (func) <jclass org.python.core.PyFunction . . .> >>> type (dir()) <jclass org.python.core.PyList . . . > >>> type(hello) <jclass org.python.core.PyInstance . . .>

Operations

This section deals mostly with functions that are longhand for operators.

Numeric Operations: cmp(), divmod(), pow(), abs(), round()

cmp(x,y) compares two numeric types. It also works for sequences, dictionaries, and other numeric objects. cmp() returns a positive number if the x argument is greater than the y argument, a negative number if the y argument is greater than the x argument, and 0 if x and y are equal.

>>> cmp(1,0) 1 >>> cmp(0,1) -1 >>> cmp(0,0) 0

cmp() is related to the equality operators (==, >=, <=, etc.). If you want these operators to work with class instances, you need to implement cmp() for the class by executing cmp(instance1, instance2), instance1 == instance2, or instance1 > instance2).

The divmod() function divides a by b and returns a tuple containing the divider and the remainder. With divmod(), these two examples are equivalent:

>>> 100 / 10, 100 % 10 (10, 0) >>> divmod(100,10) (10, 0)

The pow() function raises x to the power of y, so these two examples are the same:

>>> 5**3 125 >>> pow(5,3) 125

The abs() function returns the absolute value of a number.

>>> abs(1), abs(-1) (1, 1)

The round(x, [n]) function rounds a number with a fraction to the nearest whole integer (or, if you specify the n argument, to the nearest position in the mantissa). Here's an example.

Declare a variable containing a float with a long mantissa.

>>> myfloat = 1.1111111111111111

Round to the nearest whole integer.

>>> round(myfloat) 1.0

Round to the second decimal place in the mantissa.

>>> round(myfloat, 2) 1.11

Round to the third decimal place in the mantissa.

>>> round(myfloat, 3) 1.111

Identity: hash(), id()

The hash() function returns a number that represents the data of an object, called the hash value. Hash values are integers that can be used to efficiently compare dictionary keys.

>>> myint= 1 >>> myfloat = 1.0 >>> hash(myint) 1 >>> hash(myfloat) 1

The id(object) function assigns objects in the system a unique ID. It implements the is operator. In the following statements, id and is are functionally equivalent:

>>> dict = {} >>> id(dict)==id(dict), dict is dict (1, 1)

Class, Instance, and Modules: delattr(), getattr(), hasattr(), setattr()

The delattr(object,name) function removes attributes from a class or instance or removes variables from a module namespace. It works similarly to del(). Consider the following example, which defines an empty class, myclass, creates an instance of it, and adds attributes to the instance.

Define myclass.

>>> class myclass:pass ...

Create an instance of myclass, ci ("class instance"), and add to it the attributes "hello" and "goodbye".

>>> ci = myclass() >>> ci.hello = "hello" >>> ci.goodbye = "goodbye"

Display the attributes.

>>> vars(ci) {'goodbye': 'goodbye', 'hello': 'hello'}

Use the del keyword to delete the "hello" attribute: then display the attributes that remain.

>>> del ci.hello >>> vars(ci) {'goodbye': 'goodbye'}

Use delattr()to delete "goodbye" from the class instance, and use vars() to show that the instance has no more attributes.

>>> delattr(ci,"goodbye") >>> vars(ci) {}

Del

You can't use delattr() to remove items (key/value pairs) from a dictionary; only the del keyword can do that. del and delattr() are equivalent only for classes, instances, and modules.

Here's an example that works with a module, mymodule.py. It just defines two variables, attr1 and attr2.

attr1=1 attr2=2

Import mymodule.py into the interactive interpreter.

>>> import mymodule

Show mymodule's namespace with the dir() function.

>>> dir (mymodule) ['__builtins__', '__doc__', '__file__', '__name__', 'attr1', 'attr2']

Use delattr() to remove attr1 from the namespace.

>>> delattr(mymodule, "attr1")

Verify the removal.

>>> dir(mymodule) ['__builtins__', '__doc__', '__file__', '__name__', 'attr2']

Use del() to do the same thing with attr2.

>>> del mymodule.attr2 >>> dir(mymodule) ['__builtins__', '__doc__', '__file__', '__name__']

The getattr() function, strange as it may seem, "gets" an attribute from a class, instance, or module. Here's an example using a class, myclass2, whose instances have the attributes name and height.

Define myclass2.

>>> class myclass2: ...   def __init__(self): ...         self.name = "Bob" ...         self.height = "5'11" ... >>> ci = myclass2()

Display the attributes of the class instance.

>>> vars(ci) {'height': "5'11", 'name': 'Bob'}

Get the height attribute.

>>> getattr(ci, "height") "5'11"

There's an easier way to do this.

>>> ci.height "5'11"

But with getattr() we can get attributes dynamically at runtime.

The getattr() function also works with modules:

>>> getattr(mymodule, "attr1") 1

which is equivalent to

>>>mymodule.attr1 1

The hasattr() function checks to see if a class, instance, or module has an attribute. It returns true if so, false if not. Continuing our mymodule.py example, we have the following:

>>> hasattr(ci,"height") 1 >>> hasattr(ci,"weight") 0

hasattr() also works with modules.

>>> hasattr(mymodule, "attr1") 1

The setattr() function sets an attribute for a class, instance, or module. Still with the same example, we'll add the weight attribute to the class instance.

Determine if the ci class instance already has weight.

>>> hasattr(ci,"weight") 0

The 0 (false) value indicates no, so add it.

>>> setattr(ci,"weight", 220)

Now does it have it?

>>> hasattr(ci,"weight")

The 1 (true) value indicates yes.

We know the other way to add the weight attribute, but first we need to remove it.

>>> delattr(ci, "weight")   #remove it >>> hasattr(ci, "weight")   # make sure it is gone 0

Now we set it and check to see if it's there.

>>> ci.weight = 220 >>> hasattr(ci,"weight") 1
Working with Modules

Here's an example of how setattr(), hasattr(), and delattr() work with modules.

Import the sys module.

>>> import sys

Get the exit and version objects.

>>> getattr(sys, "exit") <built-in function exit> >>> getattr(sys, "version") '1.5.1 (#0, 07/16/98 22:30:00) [MSC SH3]'

Remove the exit() function and make sure it's gone.

>>> delattr(sys, "exit") >>> hasattr(sys, "exit") 0

Redefine the exit object in the context of the sys module.

>>> setattr(sys,"exit","exit has left the building")

Display the new exit() function.

>>> getattr(sys, "exit") 'exit has left the building'

cmp() and Classes and Dictionaries

cmp() works with many object types. For example, if left undefined, it works with class instances just as id or is does. As with numeric objects, cmp() returns 0 if the objects are equal. Here's an illustration.

Create two class instances.

>>> ci1,ci2 = myclass2(),myclass2()

Compare them.

>>> cmp(ci1,ci2) -1

Even though the values are the same, the instances are unequal because the default is to check object identity (to make sure that the variable references the same object).

Compare one instance to itself.

>>> cmp(ci1,ci1) 0

Since cmp() checks identity for equality, comparing an object to itself returns 0, which means equality.

The cmp() method defines the behavior of the equality operators. That means that the following is like using the identity operator:

>>> ci1 == ci2 0 >>> ci1 == ci1 1 >>> ci1 is ci2, ci1 is ci1 (0, 1)

Chapter 8 has an example of __cmp__ defined for the Address class. Here's an excerpt:

def __cmp__(self,other):       """       Compares one address instance to another.       If the address instances are equal the __cmp__ returns 0. If the address instances are not equal then we return a non-zero value.        """                     # To implement this all we do is compare # the dictionaries of the class                     # The __dict__ member of the instance holds # all of the instance fields # in a dictionary        return cmp(self.__dict__ ,other.__dict__)

This compares all attribute values of one instance of Address with those of another instance. Remember, the default is just to compare identity.

Sequence and Collection: len(), max(), min(), cmp()

We covered sequences and collections in Chapter 1, so we'll just review them here.

The len(s) method returns the length of a sequence or dictionary. It works with tuples, lists, and dictionaries, as shown in the following three examples:

>>> len((1,2,3)) 3 >>> len([1,2,3]) 3 >>> len({1:1,2:2,3:3} ) 3

The max(s) function returns the max value in a sequence. It uses cmp() to determine which item in the list is the greatest.

>>> max((1,2,3)) 3

The min(s) function returns the min value in the list.

>>> min((1,2,3)) 1

The cmp(x,y) method compares sequences (list and tuple) to sequences and dictionaries to dictionaries. Here's how.

Create three tuples, the first and second having equal values.

>>> list1,list2,list3=(1,2,3),(1,2,3),(1,2,4)

Compare the first and the second tuples.

>>> cmp (list1, list2) #cmp returns 0 if they are equal 0 >>> list1==list2 1

Compare the second and third tuples.

>>> cmp(list2, list3) -1 >>> cmp(list3, list2) 1 >>> list2==list3 0

Create two dictionaries.

>>> dict1,dict2 = {1:1,2:2,3:3} , {1:1,2:2,3:3}

Compare them.

1 >>> cmp (dict1, dict2) #cmp returns 0 if they are equal 0

Add an item to the first dictionary.

>>> dict1["cow"]="moo"

Compare the first and second dictionaries again.

>>> dict1==dict2 0 >>> cmp(dict1,dict2) 1

Modules: reload()

The reload() function allows you to dynamically reload a module. It comes in very handy when you're debugging code. Here's an example with the string module:

>>> import string >>> reload(string) <module 'string'>

During development of a module, it's often necessary to make minor changes. Instead of exiting the interactive interpreter, you can make your changes and then reload.

reload()needs a reference to the module. Let's say you're using the from <module> import <object> form of the import statement. In that case, you don't have a reference to the module, even though the module is loaded. (You need to exit and restart the interactive interpreter for this example.)

>>> from string import find >>> print find <built-in function find> >>> print string Traceback (innermost last):   File "<interactive input>", line 1, in ? NameError: string

Although we have access to the find() function, we don't have access to the string module, so when we try to print it out we get a NameError. To reload find() we have to first import and reload string (which puts it in the current namespace). We'll continue with our example.

Explicitly import string.

>>> import string

Reload it.

>>> reload (string) <module 'string'>

Access find()as before.

>>> del string #optionally remove string from your namespace >>> print find <built-in function find>

Reloading the string module will reload all of its code; any changes will be reflected at that time. This is a great tool for debugging your Python modules.

The __import__() function (__import__(name, [globals], [locals], [fromlist])) works like the import statement, except that it allows you to pass the name of the module as a string. Imagine a program that, given a command-line argument, loads a module and executes its test() function. You can use this test harness with many different modules with many different names. Now imagine another program that detects how it connects to the home office and, based on that information, loads the correct module to talk to the boss.

Here's an example of __import__():

>>> __import__("string") <module 'string'>

Class Operations: isinstance(), issubclass()

We covered the built-in isinstance() and issubclass() functions in Chapter 6, but let's briefly review them. We're going to use the following code, which defines a class hierarchy:

>>> class animal: ...     pass ... >>> class mammal(animal): ...   pass ... >>> class human(mammal): ...   pass ... >>> class geek: ...   pass ... >>> class programmer(geek, human): ...   pass ...

The isinstance(object,class) function determines if the instance is of a particular class. It works with the instance's base class; that is, if the human class is a subclass of the mammal class, any instance of human is also an instance of mammal. For example:

>>> Rick = programmer()

Is the Rick class instance an instance of programmer?

>>> isinstance(Rick,programmer) 1

Is Rick a geek?

>>> isinstance(Rick,geek) 1

Are programmers human?

>>> isinstance(Rick,human) 1

Since Rick is an instance of programmer and programmer is a subclass of human, Rick is an instance of human.

Of course, it doesn't stop with the immediate base classes. Rick is an instance of mammal and animal because these are in the base class hierarchy of programmer.

Is Rick a mammal?

>>> isinstance(Rick, mammal) 1

Is Rick an animal?

>>> isinstance(Rick, animal) 1

Since Rick is a human and humans are subclasses of mammals, Rick is a mammal. Since Rick is a mammal and mammals are subclasses of animals, Rick is an animal.

issubclass(class1, class2) returns whether one class is a subclass of another. Our illustration of issubclass() will continue our class hierarchy.

Is human a subclass of animal?

>>> issubclass(human, animal) 1

Is human a subclass of mammal?

>>> issubclass(human, mammal) 1

Is geek a subclass of animal?

>>> issubclass(geek,animal) 0

issubclass() doesn't work just for immediate subclasses but for subclasses anywhere in the hierarchy that have a class as a base class anywhere in their own hierarchy.

I/O: open(), raw_input()

The open(filename, [mode], [bufsize]) function returns a file object. Again, this is just a brief review since we covered I/O in Chapter 7.

Open a file for reading.

>>> file = open("\\dat\\exp.txt", "w") >>> file.write("Hello") >>> file.close()

Open a file for writing.

>>> file = open("\\dat\\exp.txt") >>> file.read() 'Hello'

The mode argument specifies read ("r"), write ("w"), read/write ("r+"), and append ("a") mode. bufsize sets the size of the buffer. Setting the buffer to zero means no buffering. (For more on buffering see Chapter 12.)

The raw_input([prompt]) function reads input from the user. The prompt tells the user what that input should be and returns it when the user hits Enter. Try following this:

>>> raw_input("Enter your age: ") Enter your age: 31 '31'

Advanced Topic: Functional Programming

You don't need to know functional programming to develop Python code, but learning it can reduce the amount of code you write.

apply(), filter(), map(), reduce

The apply(function, args, [keywords]) function needs a callable object as the function argument, which it calls with args as the argument list (and keywords as the named argument list). args is a sequence, keywords a dictionary.

The function

>>> def hello(str): ...   print "hello " + str ...

can be called with apply() like this:

>>> apply(hello,("Bobby",)) hello Bobby

Without apply() it's called like this.

>>> hello("Bobby") hello Bobby

You can use apply()to call several functions. Or you can have several functions operating on the same data.

The filter(function, list) function filters out items in a list. Its argument is a callable object that takes an item out of the list and returns true or false. Let's say the only list items we want are those that begin with R.

Create a list containing names.

>>> list = ["Mary", "Adam", "Bob", "Rick", "Robert"]

Define a function that returns true if the name starts with R.

>>> def Rfilter(name): ...   if name[0]=="R": return 1 ...   else:             return 0 ...

Invoke filter(), passing it the Rfilter and list arguments.

>>> filter(Rfilter,list) ['Rick', 'Robert']

This example is, admittedly, contrived. In a real situation, the items in the sequence can be much more complex than just strings; they can be class instances or dictionaries with 100 items, or tuples with dictionaries, class instances, and lists. Also, the function passed can be just short of rocket science. The point is that filter() returns every item in the list where the item applied to it returns a true value.

As an exercise, rewrite the above functionality with for loops instead of filter(). Which code is more concise? Which code is easier to understand? Once you answer these questions, I think you'll find that filter() is very useful.

The map(function, list) function is similar to filter(). It applies functions to every item in a list and returns the results for each function (item) call. map()'s first argument is a callable type; its second argument is a list.

As an example, let's say you have the following sequence that you want to convert into a string:

>>> seq = (72, 105, 32, 77, 111, 109)

which you can do with a for loop.

>>> list = [] >>> for item in seq: ...   list.append(chr(item)) ... >>> from string import join >>> str = join(list,"")

After this code executes, str will contain a string version of the sequence, and it will take only four lines (we won't count from string import join). With the map() function, you can do all four lines of code in one method call.

>>> str = join(map(chr,seq),"")

Note that the call to map() is inside the join() function call.

You may be wondering what str contains. To unravel this mystery, enter in the code example.

>>> str

The reduce(function, list, [initializer]) function is very similar to filter() and map() in that a function parameter is applied to each item in a sequence. However, instead of returning a list it returns one value.

Let's say that you want to sum up the following list (the list variable is really a tuple):

>>> list = (1,2,3,4,5,6,7,8,9,10)

To do so with a for loop, you need to do something like this:

>>> sum=0 >>> for num in list: ...   sum = sum + num >>> sum 55

With reduce(), you do something like this:

>>> def add(a,b): return a + b ... >>> reduce (add,list) 55

which cuts out two lines of code.

If you want to cut out a third line, you can rewrite the above with a lambda function, which turns four lines into one (how very Pythonesque).

>>> reduce(lambda a,b: a+b,list) 55

Lambdas are a new concept. Think of them as anonymous functions but without names or parentheses. If you want to know more about lambda functions, consult the Python documentation.

Although powerful and elegant, reduce(), apply(), map(), and filter() (and, for that matter, lambdas) can be confusing. Don't let them trip you up, though you don't need to master them to program in Python.

Advanced exec and eval

Imagine easily sending code to update changes to a program or easily moving code around the network to update remote clients. How about adding scriptability so that end users can write scripts to automate common tasks? In other languages, these things are hard to accomplish. In Python they're built into the language.

compile()

The compile(string, filename, kind) function converts a string into a code object that represents Python bytecode. The filename argument states the origin of the code, that is, the file name; the kind argument specifies how the code should be compiled based on the contents of the string argument. There are three choices for kind:

  • exec a group of statements

  • eval a single expression

  • single a single statement

compile() works in conjunction with the eval statement, which you use to execute the code object. More than likely you'll use it to execute a string representing code over and over again so that eval won't have to execute the string by recompiling the code object each time.

Here's an example of compile() with the exec kind argument. It pretends that it has read the string from a file called friends.py.

>>> string = """ ... friends = ['Ross','Rachel','Chandler','Joey','Tom','Jerry','Monica'] ... for myfriend in friends: ...   print "Hello " + myfriend ... """ >>> code = compile(string,"Friends.py","exec") >>> eval(code) Hello Ross Hello Rachel Hello Chandler Hello Joey Hello Tom Hello Jerry Hello Monica >>>

Here's an example compiling an expression that returns a dictionary:

>>> str = "{1:1,2:2,3:3,4:4} " >>> cd = compile (str,"string","eval") >>> eval(cd) {4: 4, 3: 3, 2: 2, 1: 1} >>> dict = eval(cd) >>> type (dict) <jclass org.python.core.PyDictionary at 6190231>

which compiles a single statement:

>>> cd2 = compile("""print "Hello World" """, "string", "single") >>> eval (cd2) Hello World

Of course, we've covered eval(expressions, [globals], [locals]) quite a few times. Here we'll drill down to the details that can make you stumble.

globals and locals

eval's globals and locals arguments are dictionaries that contain the global variables, where the keys are the variable names and the values are the objects to which the variables refer. Not specifying globals or locals is the same as doing this:

eval(str, globals(), locals())

which passes the variables from the current namespace.

Here's an example of calling an eval statement:

>>> a = 1 >>> eval("a") 1

Since the a variable is in the global namespace, and we're not passing a dictionary for the global variables, it's the one used.

In this next call to eval, we pass a dictionary for the globals argument. You can see that the value of a in the dictionary overrides the value of a in the global area of the module.

>>> eval("a", {"a":2} ) 2

Here we pass a variable named a in the locals dictionary. The inner namespace locals overrides the value of the a global dictionary.

>>> eval("a",{"a":2} , {"a":3} ) 3

Continuing this example, here we use a local a (that is, local to the func() function). You can see that the a in the local area takes precedence over the a in the global area (where we set a to 1).

>>> def func(): ...   a=4 ...   print eval("a") ... >>> func() 4

execfile()

The execfile(file, [globals], [locals]) function acts just like the exec statement, except that it reads the contents of a file and executes it. As with eval, you can specify globals and locals arguments. Execfile() may seem a lot like import(), but the code executed with it acts as if it were executed in the current namespace. There is no namespace management with execfile as when a module is imported.

Here's an example of exec printing 'hello world' from a string.

>>> exec "print 'hello world'" hello world

As an exercise, create a text file containing Python code that prints 'hello world' to the console. Then, in the interactive interpreter, read and execute the file with execfile().

Summary

Of all of the chapters so far, this one was the most fun to write, simply because Python's numerous built-in functions make simple things even simpler and impossible things possible. We reviewed a lot from other chapters, but we also covered many new items, such as functional programming and executing scripts.

CONTENTS


Python Programming with the JavaT Class Libraries. A Tutorial for Building Web and Enterprise Applications with Jython
Python Programming with the Javaв„ў Class Libraries: A Tutorial for Building Web and Enterprise Applications with Jython
ISBN: 0201616165
EAN: 2147483647
Year: 2001
Pages: 25

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net