I l@ve RuBoard |
The dir function is a built-in function: it lives in the built-in namespace. Applying the LGB rule means that the function is always available, and that no import statement is needed to access it.[1] You've already encountered many of the built-in functions, such as len, open, type, list, map, range, reload. You can find them listed with the standard exceptions in the _ _builtins__ namespace:
[1] It also means that if you define a local or module-global reference with the same name, subsequent uses of dir will use your new variable instead of the built-in version. This feature is the source of some subtle bugs; one of us recently wrote a program that used a variable called o and a list of such variables called os (as in the plural of o). Surprise surprise, the (supposedly unrelated) previously bugfree code that used os.system now complained of AttributeErrors! Another frequent bug of the same kind is doing type = type(myObject), which works only the first time around, since it results in assigning to a new local variable (called type) a reference to the type of whatever myObject was. This local variable is what Python tries (and fails) to call the second time around.
>>> dir(__builtins__) ['ArithmeticError', 'AssertionError', 'AttributeError', 'EOFError', 'Ellipsis','Exception', 'FloatingPointError', 'IOError', 'ImportError', 'IndexError','KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError','None', 'OverflowError', 'RuntimeError', 'StandardError', 'SyntaxError','SystemError', 'SystemExit', 'TypeError', 'ValueError', 'ZeroDivisionError','__debug__', '__doc__', '__import__', '__name__', 'abs', 'apply', 'callable','chr', 'cmp', 'coerce', 'compile', 'complex', 'delattr', 'dir', 'divmod', 'eval','execfile', 'filter', 'float', 'getattr', 'globals', 'hasattr', 'hash', 'hex','id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'len', 'list','locals', 'long', 'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'round', 'setattr', 'slice', 'str','tuple', 'type', 'vars', 'xrange']
A few functions are used for converting between object types. We've already seen str, which takes anything and returns a string representation of it, and list and tuple, which take sequences and return list and tuple versions of them, respectively. int, complex, float, and long take numbers and convert them to their respective types. hex and oct take integers (int or long) as arguments and return string representations of them in hexadecimal or octal format, respectively.
int , long , and float have additional features that can be confusing. First, int and long truncate their numeric arguments if necessary to perform the operation, thereby losing information and performing a conversion that may not be what you want (the round built-in rounds numbers the standard way and returns a float). Second, int, long, and float convert strings to their respective types, provided the strings are valid integer (or long, or float) literals:[2]
[2] Literals are the text strings that are converted to numbers early in the Python compilation process. So, the string "1244" in your Python program file (which is necessarily a string) is a valid integer literal, but "def foo():" isn't.
>>> int(1.0), int(1.4), int(1.9), round(1.9), int(round(1.9)) (1, 1, 1, 2.0, 2) >>> int("1") 1 >>> int("1.2") # this doesn't work Traceback (innermost last): File "<stdin>", line 1, in ? ValueError: invalid literal for int(): 1.2 >>> int("1.0") #neither does this Traceback (innermost last): # since 1.0 is also not a valid File "<stdin>", line 1, in ? # integer literal ValueError: invalid literal for int(): 1.0 >>> hex(1000), oct(1000), complex(1000), long(1000) ('0x3e8', '01750', (1000+0j), 1000L)
Given the behavior of int, it may make sense in some cases to use a custom variant that does only conversion, refusing to truncate:
>>> def safeint(candidate): ... import math ... truncated = math.floor(float(candidate)) ... rounded = round(float(candidate)) ... if truncated == rounded: ... return int(truncated) ... else: ... raise ValueError, "argument would lose precision when cast to integer" ... >>> safeint(3.0) 3 >>> safeint("3.0") 3 >>> safeint(3.1) Traceback (innermost last): File "<stdin>", line 1, in ? File "<stdin>", line 6, in safeint ValueError: argument would lose precision when cast to integer
The abs built-in returns the absolute value of scalars (integers, longs, floats) and the magnitude of complex numbers (the square root of the sum of the squared real and imaginary parts):
>>> abs(-1), abs(-1.2), abs(-3+4j) (1, 1.2, 5.0) # 5 is sqrt(3*3 + 4*4)
The ord and chr functions return the ASCII value of single characters and vice versa, respectively:
>>> map(ord, "test") # remember that strings are sequences [116, 101, 115, 116] # of characters, so map can be used >>> chr(64) '@' >>> ord('@') 64 # map returns a list of single characters, so it # needs to be 'join'ed into a str >>> map(chr, (83, 112, 97, 109, 33)) ['S', 'p', 'a', 'm', '! '] >>> import string >>> string.join(map(chr, (83, 112, 97, 109, 33)), '') 'Spam!'
The cmp built-in returns a negative integer, 0, or a positive integer, depending on whether its first argument is greater than, equal to, or less than its second one. It's worth emphasizing that cmp works with more than just numbers; it compares characters using their ASCII values, and sequences are compared by comparing their elements. Comparisons can raise exceptions, so the comparison function is not guaranteed to work on all objects, but all reasonable comparisons will work. The comparison process used by cmp is the same as that used by the sort method of lists. It's also used by the built-ins min and max, which return the smallest and largest elements of the objects they are called with, dealing reasonably with sequences:
>>> min("pif", "paf", "pof") # when called with multiple 'paf' arguments # return appropriate one >>> min("ZELDA!"), max("ZELDA!") # when called with a sequence, '!', 'Z' # return the min/max element of it
Table 8.1 summarizes the built-in functions dealing with type conversions.
The four built-in functions hasattr , getattr, setattr, and delattr test attribute existence, get, set, and delete attributes of namespaces, respectively, given the attribute's name as the second argument. They are useful when manipulating objects and attributes whose names aren't available beforehand. They can be used with modules, classes, and instances, and are summarized in Table 8.2.
We saw these built-ins put to good use in the examples in Chapter 6, but for now, consider a toy example that creates a specified attribute in a given namespace (in this case, a class object), or increments it if it's already there:
>>> def increment_attribute(object, attrname): ... if not hasattr(object, attrname): ... setattr(object, attrname, 1) ... else: ... setattr(object, attrname, getattr(object, attrname) + 1) ... >>> class Test: pass ... >>> aname = 'foo' >>> increment_attribute(Test, aname) # create Test.foo and set it to 1 >>> increment_attribute(Test, aname) # increment Test.foo >>> Test.foo 2
In Python 1.5.2, an optional third argument to getattr has been added that specifies what value to use if the object doesn't have the specified argument. Thus the code above can now be simplified:
setattr(object, attrname, getattr(object, attrname, 0) + 1)
The last set of built-in functions in this section have to do with creating, manipulating, and calling Python code. See Table 8.3 for a summary.
Name |
Behavior |
---|---|
Executes the code in a module as part of the importing and returns the module object |
|
Executes the specified code (string, file, or compiled code object) in the optionally specified global and local namespaces |
|
Compiles the string into a code object (see following Note) |
|
Executes the program in the specified filename, using the optionally specified global and local namespaces |
|
Evaluates the specified expression (string or compiled code object) in the optionally specified global and local namespaces |
It's a simple matter to write programs that run other programs. Shortly, we'll talk about ways to call any program from within a Python program. And we've seen the import statement that executes code existing in files on the Python path. There are several mechanisms that let you execute arbitrary Python code. The first uses exec, which is a statement, not a function. Here is the exec syntax:
exec code [ in globaldict [, localdict]]
As you can see, exec takes between one and three arguments. The first argument must contain Python code—either in a string, as in the following example; in an open file object; or in a compiled code object (more on this later). For example:
>>> code = "x = 'Something'" >>> x = "Nothing" # sets the value of x >>> exec code # modifies the value of x! >>> print x 'Something'
exec can take optional arguments. If a single dictionary argument is provided (after the then-mandatory in word), it's used as both the local and global namespaces for the execution of the specified code. If two dictionary arguments are provided, they are used as the global and local namespaces, respectively. If both arguments are omitted, as in the previous example, the current global and local namespaces are used.
|
A related function to the exec statement is the execfile built-in function, which works similarly to exec, but its first argument must be the filename of a Python script instead of a file object or string (remember that file objects are the things the open built-in returns when it's passed a filename). Thus, if you want your Python script to start by running its arguments as Python scripts, you can do something like:
import sys for argument in sys.argv[1:]: # we'll skip ourselves, or it'll loop! execfile(argument) # do whatever
Two more functions can execute Python code. The first is the eval function, which takes a code string (and the by now usual optional pair of dictionaries) or a compiled code object and returns the evaluation of that expression. For example:
>>> z = eval("'xo'*10") >>> print z 'xoxoxoxoxoxoxoxoxoxo'
The eval function can't work with statements, as shown in the following example, because expressions and statements are different syntactic beasts:
>>> z = eval("x = 3") Traceback (innermost last): File "<stdin>", line 1, in ? File "<string>", line 1 x = 3 ^ SyntaxError: invalid syntax
The last function that executes code is apply. It's called with a callable object, an optional tuple of the positional arguments, and an optional dictionary of the keywords arguments. A callable object is any function (standard functions, methods, etc.), any class object (that creates an instance when called), or any instance of a class that defines a _ _call__ method. If you're not sure what's callable (e.g., if it's an argument to a function), test it using the callable built-in, which returns true if the object it's called with is callable.[3]
[3] You can find many things about callable objects, such as how many arguments they expect and what the names and default values of their arguments are by checking the Language Reference for details, especially Section 3.2, which describes all attributes for each type.
>>> callable(sys.exit), type(sys.exit) (1, <type 'builtin_function_or_method'>) >>> callable(sys.version), type(sys.version) (0, <type 'string'>)
There are other built-in functions we haven't covered; if you're curious, check a reference source such as the Library Reference (Section 2.3).
I l@ve RuBoard |