Python Calling functions and methods. Using objects and modules.
The whole ethos of Python is about code reuse. About not re-inventing the wheel if someone else has already invented the wheel, and indeed about adapting their wheels if they're not quite what you need. This module, then, covers code reuse.
There are between 100 and 150 built in objects in Python when you start an interpretter (remember that everyting is an object in Python) and about a half of those are built in functions.
PASSING PARAMETERS AND RETURNING VALUES
You call a builtin function by name, and in brackets after the name you place any values that you're passing in to the function. A function will normally return a resulting value to you, and that values may be assigned to a variable of used within an expression (or have a method run on it).
Sample = "It's a long way to Tipperary"
syze = len(Sample)
print "The length of \"",Sample,"\" is",syze,"characters"
sequence = range(1,21,2)
addedup = sum(sequence)
print "sequence is",sequence,"which sums to",addedup
Which runs as follows:
wizard:y200.d graham$ python biff
The length of " It's a long way to Tipperary " is 28 characters
sequence is [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] which sums to 100
You'll already have seen some other built in functions in use in your very early Python examples on this course - input and raw_input, for example, and we'll introduce you to more of the as the course goes on. There's even a built in function called dir which lets you see what names (including functions) you have loaded into a particular area, and if you use
from the interactive command line, you'll get a full list of the builtins. Please don't try and learn about all of them; many are pretty esoteric and you're unlikely to ever need them. But here's the current (Python 2.7) list:
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
Methods on built in data types
Built in functions are wide ranging, and operate at all levels of Python. Built in methods are functions which operate on a particular type of variable only, and the syntax is different.
days = ["Monday","Tuesday","Wednesday"]
r1 = len(days)
r2 = days.count("Tuesday")
r3 = days.count("Thursday")
which runs as follows
wizard:y200.d graham$ python lenco
3 1 0
Note - you can use "len" on anything, but this version of "count" is specific to a list
Methods often make changes to the object on which the method is run, so it's not uncommon for there to be no return value
days = ["Monday","Wednesday"]
Some functionallity - such as lists and strings themselves and many of the opertions we have performed on them - are needed so often that they're loaded by default into every Python program that you run. But other functionallity is less commonly required - it's needed commonly enough to be distributed with Python, perhaps, but not so commonly as to be loaded into (and therefore clutter up, add to the footprint of, and slow down) every Python program.
This extra functionallity is available to you as modules (you'll learn about packages of modules later).
LOADING AND CALLING
You can load in module in 2 different ways - using <b>from</b> or using <b>import</b>
With from, all the names that you load in become a part of the namespace (familiy) that you're working within - so the extra names are then quickly and easily available to you. This has the advantage that they can be called up by a very short piece of code, but the disadvantage that they'll overwrite anything else that's already loaded with the same name.
from os import *
contains = listdir(".")
With import, the names are brought into their own namespace (family) and so there's no risk of them overwriting anything else. Its also clearer when the calling program references them as to their source, but if you're making lots of calls to them, it can get rather repetitive.
contains = os.listdir(".")
Those examples run as follows:
wizard:y200.d graham$ python fromlist
['appy', 'biff', 'fromlist', 'importlist', 'lenco']
wizard:y200.d graham$ python importlist
['appy', 'biff', 'fromlist', 'importlist', 'lenco']
With both from and import, the from or import statement are performed at run time, and part of the action of loading is to run the code that's within the module. That means that you can conditionally load something if you wish, and that you could even repeatedly load it within a loop. This latter is not recommeneded under normal circumstances, but is is interesting to note that you can replace modules, methods and functions while your program is running, which is not a feature commonly shared with other languages.
Both from and import have their problems - neither is ideal for all circumastances, which is why you have both.
- With from, you can limit which names are loaded in order to only overwrite / provide the elements you want in your code. e.g.
from os import listdir
- With import, you can add as "as" clause to rename the module as you load it to something shorter.
import numpy as np
is very common.
How do you find out what's available?
- There's a global module index at http://docs.python.org/modindex.html
- From there you can link to the manual page which tells you more about it
- You can also import it into an interactive Python shell and use
and then __doc__ on the module as a whole and to its individual object members
From the long list, the following are ones that we use most during courses ...
- cgi - common gateway interface to the web
- copy - deep copy of an object
- Cpickle and pickle - serialising an object
- cProfile and profile - code profiler - what's been used how many times
- doctest - code testing module to check it does what it says on the tin
- ftplib - FTP client
- getopt - handling command line options
- HTMLParser - parsing HTML and XML
- httplib - HTTP and HTTPS clients
- json - handling json format data
- keyword - checking whether a word is a Python keywork
- marshall - serialising a sinmple object
- math - maths functions (trig, log, etc)
- os - Operating system dependent function
- os.path - Operating System function which have path (/ and \) dependecies
- popen2 - running a parallel process and piping from / to it
- pydoc - python documentation handler
- random - random number, shuffle, etc
- re - regular expressions
- shelve - storing and retreiving serialised objects
- socket - network protocol low level handlers (used by other modules)
- sys - system values - "interfacing to the main computer"
- tempfile - handling temporaru files
- time - date and time functions
- timeit - monitoring the performance of a chunk of code
- Tkinter - The Tk Graphic User Interface
- unittest - regression testing
- urllib - handling web pages from a Python program
- urllib2 - handling web pages from a Python program (version 2)
And these are some of the modules which we most often load in addition to the standard
- matplotlib - plotting and graphing
- numpy - numerical data type handler - Python wrapper to C functionallity
- scipy - scientific calculations on to of numpy
- pyplot - Python Plot library
- networkx - data set manipulation
OPTIONAL AND KEYWORD PARAMETERS, GLOBALS, PROPERTIES AND STATICS.
There is more flexibilty in calling sequences to functions and methds that the ones we have introduced in this module. So far, all the parameters we have show you have been mandarory, and position dependent. However, there are two other types of paramaters too
1. You may have OPTIONAL parameters. There always come after mandatory parameters. They are still positional, but if nor specified then the function / method will take a default value. Note that you may not write ,, in your calling sequence to leave out an intermediate parameter, so it's up to the designer who uses optional parameters to put the most optional on the end.
2. You may also call with named parameters - that's where you pass in parameters with specific names which the method called will recognise.
Here's an example showing what these calls may look like:
import taxcalcs as tc
amount = float(raw_input("How much did you spend? "))
net = tc.getnet(amount,25,country="Denmark",comment="demo",type="VAT",another=tc.gettax)
print "That was",net,"for the merchant (Denmark)"
net = tc.getnet(amount,country="Slovenia",taxrate=20,year=2008,type="VAT")
print "That was",net,"for the merchant (Slovenia)"
The reference to tc.copyright is a PROPERTY - a variable within an object than can be read and written. Properties (and attributes) have some use and are covered later on the course.
You may occasionally find that a function or method uses a global variable. That's a variable who's name you are told which you must set before calling a function or method, or which mysteriously turns up after you have completed the running of a function or method. These are occasionally useful, but caution is strongly advised; they provide you with a very tempting way to write code which is very hard indeed to maintain or reuse.
See also Python Programming course