Many of our demonstrations on the Well House Consultants site show individual features of a language - taken in isolaion to show you how they work. However, during a course we usually write further examples to show you how features work in combination to give a total result / solution to an application.
On yesterday's Python course, I wrote such a complete example showing many of the features and how they interact - complete source code (opens in a separate window)
[here].
What does that illustrate?
Decorators
A method which can be applied as a wrapper around other methods. In my example, I used a decorator to count the number of times each method was called so that I could end the running or my program with a "coverage map" - a table of how many times each method had been called. That's potentially very useful when we come to look at efficiency later!
Factory
A factory method - a piece of code that's within a class or group of classes that takes raw data in what's probably a standard format for a series of applications based on the same data and converts it into an object or objects, with the class (type) of the object being created actually being decided based on the raw data rather than having to be worked out in the user application.
Inheritance
How all the common code to a lot of slighly different types of data can be held in a single class, and the separate classes based on the initial one can be defined just in terms of the changes / differences, rather than each having to be defined completely itself and potentially with a lot of duplication.
Comparators
Object (dynamic) methods usually work on a single object. Class (static) methods usually work on a class as a whole. However, for overridden operators such as + (__add__) you want methods that work on two objects. The sample program we wrote shows how you can pass in two parameters - one before the "." and the other as a conventional parameter in order to write two-object methods.
Polymorphism
The characteristic of different methods being called (and so different logic) being run by a single call in the source code. If you have a variable that may contain an object of type "a" or an object of type "b", you don't have to work out which it is in your own program to call the appropriate logic - Python (or any OO language) does that for you.
To string override
When you print out an object, what do you get? In the generic / default case, all your program can do is tell you the type of object and the address at which it's stored - that's the only common data. However, in Python you can provide a method called __str__ which tells Python how to convert a particular type of object into a string for output purposes.
Formatting
Default output for floats is 14 significant figures. For integers, the interpretter uses a filed just as wide as it needs. Our example shows you how you can override the default format using the
% operator.
Exceptions
Exceptions are a way of catching errors when things go wrong, and of handling function calls where they need to return the answer that "there is no answer to that". Exceptions are valuable as a safety net under code which may (often through user error) need to perform some sort of recovery process - perhaps as a result of being asked to read data from a file that does not exist.
Static methods
Most methods in a class will operate on specific object members of that class, but you may ocasioanlly have a method which you want to run on the class as a whole - for example to give you soe interal statistics about the class. You may also want to use static or class methods for utility code which is naturally written and maintained and loaded with the class, but does not refer to specific existing objects. A good example of this is a
factory method
Object state caching
If you have complex calculations to do on an object, should you do so as you set the object up, or as you call for the results? As far as the object user is concerned, it doesn't make any difference - if you go to eat in a restaurant, it doesn't matter if the table was set just after the previous eaters left or just before you arrived. But it CAN, in coding terms, make an effiency difference. An efficient way is to calculate a result only when it's needed (for the first time), but then store the result so that it can be called up again from that store if it's requested second and subsequent times.
__class__.__name__
Only VERY rarely should you need to ask "what type of object is this". You can do so using .__class__.__name__. You can also use the
isinstance operator to find out whether an object belongs to a class (and that means that it's a member of a class or of a class that's derived from it. That very rare occasion, by the way, is when you're wanting to check that one of your users has called your method with the right type of data.
Test Harness and Unit Testing
The test
if __name__ == "__main__":
lets us include a test program within a module, which runs if the module is called up directly at the command line. For more thorough testing, you could use the
doctest or the
unittest module ... and there's an example of the
unittest module in use to show how to test the class that I'me writing about in this example
[here].
Generator / Iterate through file handle
You can "slurp" a whole file into a list using
readlines, but that can result in a huge memory footprint for your process if you have a huge file. The
xreadlines method was added a number of releases ago as an iterator to let you read data just ahead of yourself (see also - Generator); that's now been further enhanced so that you can simply iterate through the file handle in a for loop:
for line in fh:
pass
When Python requires a block but you don't want to do anything in the block, you can use a
pass.
*args and **kwargs
Positional command line arguments can be picked up by individual name ... or they can all be read into a list if you put a
* in front of the receiving variable name in the function / method definition. You can also apply named parameters to a function or method in Python, and they can all be picked up using the
** notation. It's become a sort of convention to use the names
args and
kwargs for these. When would you use these? When you're writing a decorator, for example - you want the flexibility of being able to wrap just about any method into another, irrespective of how many or what type of arguments it's called with.
import
Loading modules from elsewhere .... you can use
from to bring them into your own namespace, or
import to bring them into their own namespace.
From make for quick and easy referencing to them, but is
not in general recommended since it can quickly lead to shared / duplicated / overwritten names. Especially if you bring in a lot of extra code, you should do so with
import
The sys module
The
sys module provides you with a whole load of accessors to your immediate environment. In just this one example program, I have used:
• sys.stderr - for output of error messages
• sys.argv - to collect the program name (argv[0]) and command line parameters
• sys.exit - to return to the calling program with a status code
• sys.stdin - to make specific reference to keyboard / redirected or piped input channel
stderr
You can output from your program to the default
stdout amd to
stderr - both of which will default to your user's terminal window. But you are strongly encouraged to send error messages and log progress to
stderr. By doing so, you're providing your user with a way of redirecting
only the data output to a file or another process, leving the operational messages still sent to the screen where the user can read them.
Parent Constructor
Objects are created through constructor methods. They can be placed in any class, and be inherited to that you don't have to specify one for each and every class. However, if you want to describe how to define an object in a subclass to be "like the one in my parent class, but with the following differences", how can you do it? By providing a constructor that uses the
super call to invoke the parent's constructor, and then make any changes / additions that you need for the subclass.
direct variable access and attributes (properties)
You can reference variables which are held within your object directly. Quick and easy to write the code, but potentially very hard to maintain as you're removing the code layer where you can make changes between the user's calling code and the storage type and name chosen within your objects.
You CAN access a name without () notation if you define it as a
property. This:
people = property(getpeeps,None)
allows me to add
.people onto the end of an object name and cause the
getpeeps() method to be invoked at runtime. The use of
None means that I do NOT have an equivalent way of writing to the pseudovariable under the name .people.
Properties provide the user of your classes with a syntax that's the same as that used for direct variable access, and thus an escape hatch if a lot of user code makes direct variable calls which have become impractical to maintain during code restructures.
/usr/bin/env command line
The first line of a Pythn script on a Unix or Linux system may start with
#! to indicate the file under which the file is to be interpressted - so
#!/usr/bin/python
or
#!/bin/python
This heas meant that the first line of a script has sometimes needed changing as the script is moved around, even between machines running the same OS but differently configured. The
env command, consistently available in
/usr/bin, may be used to locate and redirect the script to Python no matter where it is on a particular system!
#!/usr/bin/env python
Read from file named on command line, or from stdin
And finally ... our example program shows an example of a program that reads data from a file named on the command line, or if there is no such file named it reads from
stdin.
If you want to learn more about Python ... please have a look at the resources on our web site - there are many listed subject by subject
[here], or come on one of our
Python courses.
(written 2011-09-16)
Associated topics are indexed as below, or enter http://melksh.am/nnnn for individual articles
Y301 - Python - Class Interaction - an example [236] Tapping in on resources - (2005-03-05)
[964] Practical polymorphism in action - (2006-12-04)
Y212 - Python - Code testing, patterns, profiles and optimisation. [235] Preparation for a day's work - (2005-03-04)
[1140] Python GTK - Widget, Packing, Event and Feedback example - (2007-04-09)
[1146] __new__ v __init__ - python constructor alternatives? - (2007-04-14)
[1148] Python decorators - wrapping a method call in extra code - (2007-04-15)
[1555] Advanced Python, Perl, PHP and Tcl training courses / classes - (2008-02-25)
[2123] Using Python with OpenOffice - (2009-04-09)
[2616] Defining a static method - Java, Python and Ruby - (2010-02-01)
[3441] Pressing ^C in a Python program. Also Progress Bar. - (2011-09-15)
[3464] Passing optional and named parameters to python methods - (2011-10-04)
[3478] Testing your Python classes with the unittest package - how to - (2011-10-14)
[3658] Using Make for a distribution - (2012-03-17)
[4090] Test Driven Development in Python - Customer Comes First - (2013-05-16)
[4326] Learning to program - comments, documentation and test code - (2014-11-22)
[4344] Python base and inherited classes, test harness and unit testing - new examples - (2014-12-07)
[4446] Combining tests into suites, and suites into bigger suites - Python and unittest - (2015-03-01)
[4470] Testing in Python 3 - unittest, doctest and __name__ == __main__ too. - (2015-04-21)
[4538] Flask and unittest - hello web app test world - (2015-10-15)
[4540] Unittest of a Flask application including forms - (2015-10-15)
[4542] The principle of mocking - and the Python Mock package - (2015-10-17)
[4617] Pytest - starting example - (2016-01-07)
[4618] Pytest - second example beyond hello world - (2016-01-08)
[4716] Profiling your Python program - (2016-11-01)
Y117 - Python - Already written modules [2020] Learning Python - many new example programs - (2009-01-31)
[2506] Good example of recursion in Python - analyse an RSS feed - (2009-11-18)
[2890] Dates and times in Python - (2010-07-27)
[2931] Syncronise - software, trains, and buses. Please! - (2010-08-22)
[3465] How can I do an FTP transfer in Python? - (2011-10-05)
[3479] Practical Extraction and Reporting - using Python and Extreme Programming - (2011-10-14)
[4085] JSON from Python - first principles, easy example - (2013-05-13)
[4086] Cacheing class for Python - using a local SQLite database as a key/value store - (2013-05-14)
[4441] Reading command line parameters in Python - (2015-02-23)
[4452] Binary data handling - Python and Perl - (2015-03-09)
[4696] Programming with random numbers - yet re-using the same values for testing - (2016-06-22)
[4697] Month, Day, Year number to day of week and month names in Python - English and Swedish - (2016-06-23)
[4708] Scons - a build system in Python - building hello world - (2016-10-29)
[4710] Searching a Json or XML structure for a specific key / value pair in Python - (2016-10-30)
Y115 - Additional Python Facilities [183] The elegance of Python - (2005-01-19)
[208] Examples - Gadfly, NI Number, and Tcl to C interface - (2005-02-10)
[239] What and why for the epoch - (2005-03-08)
[463] Splitting the difference - (2005-10-13)
[663] Python to MySQL - (2006-03-31)
[672] Keeping your regular expressions simple - (2006-04-05)
[753] Python 3000 - the next generation - (2006-06-09)
[901] Python - listing out the contents of all variables - (2006-10-21)
[1043] Sending an email from Python - (2007-01-18)
[1136] Buffering output - why it is done and issues raised in Tcl, Perl, Python and PHP - (2007-04-06)
[1149] Turning objects into something you can store - Pickling (Python) - (2007-04-15)
[1305] Regular expressions made easy - building from components - (2007-08-16)
[1336] Ignore case in Regular Expression - (2007-09-08)
[1337] A series of tyre damages - (2007-09-08)
[1876] Python Regular Expressions - (2008-11-08)
[2407] Testing code in Python - doctest, unittest and others - (2009-09-16)
[2435] Serialization - storing and reloading objects - (2009-10-04)
[2462] Python - how it saves on compile time - (2009-10-20)
[2655] Python - what is going on around me? - (2010-02-28)
[2721] Regular Expressions in Python - (2010-04-14)
[2745] Connecting Python to sqlite and MySQL databases - (2010-04-28)
[2746] Model - View - Controller demo, Sqlite - Python 3 - Qt4 - (2010-04-29)
[2764] Python decorators - your own, staticmethod and classmethod - (2010-05-14)
[2765] Running operating system commands from your Python program - (2010-05-14)
[2786] Factory methods and SqLite in use in a Python teaching example - (2010-05-29)
[2790] Joining a MySQL table from within a Python program - (2010-06-02)
[3089] Python regular expressions - repeating, splitting, lookahead and lookbehind - (2010-12-17)
[3469] Teaching dilemma - old tricks and techniques, or recent enhancements? - (2011-10-08)
[4211] Handling JSON in Python (and a csv, marshall and pickle comparison) - (2013-11-16)
[4298] Python - an interesting application - (2014-09-18)
[4439] Json is the new marshall, pickle and cPickle / Python - (2015-02-22)
[4451] Running an operating system command from your Python program - the new way with the subprocess module - (2015-03-06)
[4536] Json load from URL, recursive display, Python 3.4 - (2015-10-14)
[4593] Command line parameter handling in Python via the argparse module - (2015-12-08)
[4709] Some gems from Intermediate Python - (2016-10-30)
Y112 - Python - Objects - Intermediate [296] Using a Python dictionary as a holder of object attributes - (2005-04-30)
[383] Overloading of operators on standard objects in Python - (2005-07-19)
[477] Class, static and unbound variables - (2005-10-25)
[656] Think about your design even if you don't use full UML - (2006-03-24)
[831] Comparison of Object Oriented Philosophy - Python, Java, C++, Perl - (2006-08-13)
[903] Pieces of Python - (2006-10-23)
[1217] What are factory and singleton classes? - (2007-06-04)
[1517] Python - formatting objects - (2008-01-24)
[1644] Using a utility method to construct objects of different types - Python - (2008-05-17)
[1661] Equality, sameness and identity - Python - (2008-05-31)
[1819] Calling base class constructors - (2008-10-03)
[2368] Python - fresh examples of all the fundamentals - (2009-08-20)
[2409] TypeError: super() argument 1 must be type, not classobj (Python) - (2009-09-18)
[2485] How do I set up a constant in Python? - (2009-10-31)
[2693] Methods that run on classes (static methods) in Python - (2010-03-25)
[2717] The Multiple Inheritance Conundrum, interfaces and mixins - (2010-04-11)
[2720] Multiple inheritance in Python - complete working example - (2010-04-14)
[2722] Mixins example in Python - (2010-04-14)
[2785] The Light bulb moment when people see how Object Orientation works in real use - (2010-05-28)
[2889] Should Python classes each be in their own file? - (2010-07-27)
[2905] Defining static methods in Python - (2010-08-05)
[2994] Python - some common questions answered in code examples - (2010-10-10)
[3002] A list of special method and attribute names in Python - (2010-10-17)
[3472] Static variables in functions - and better ways using objects - (2011-10-10)
[3524] Metaclasses (Python) and Metatables (Lua) - (2011-11-17)
[3796] Backquote, backtic, str and repr in Python - conversion object to string - (2012-07-05)
[3887] Inheritance, Composition and Associated objects - when to use which - Python example - (2012-10-10)
[4028] Really Simple Class and Inheritance example in Python - (2013-03-04)
[4094] Python Properties - how and why - (2013-05-18)
[4356] Object factories in C++, Python, PHP and Perl - (2014-12-19)
[4366] Changing what operators do on objects - a comparison across different programming languages - (2014-12-26)
[4410] A good example of recursion - a real use in Python - (2015-02-01)
[4449] Spike solution, refactoring into encapsulated object methods - good design practise - (2015-03-05)
[4450] Deciding whether to use parameters, conditional statements or subclasses - (2015-03-05)
[4541] Setting up and tearing down with the Python with keyword - (2015-10-16)
[4649] Object and Static methods - what is the difference; example in Python 3 - (2016-02-17)
[4717] with in Python - examples of use, and of defining your own context - (2016-11-02)
[4718] Defining an object that is a modified standard type in Python - (2016-11-02)
[4719] Nesting decorators - (2016-11-02)
Y110 - Python - File Handling [114] Relative or absolute milkman - (2004-11-10)
[1442] Reading a file multiple times - file pointers - (2007-11-23)
[2011] Conversion of OSI grid references to Eastings and Northings - (2009-01-28)
[2282] Checking robots.txt from Python - (2009-07-12)
[2870] Old prices - what would the equivalent price have been in 1966? - (2010-07-14)
[3083] Python - fresh examples from recent courses - (2010-12-11)
[3558] Python or Lua - which should I use / learn? - (2011-12-21)
[3764] Shell, Awk, Perl of Python? - (2012-06-14)
[4438] Loving programming in Python - and ready to teach YOU how - (2015-02-22)
[4663] Easy data to object mapping (csv and Python) - (2016-03-24)
Some other Articles
Awk v PerlPerl and CGI - simple form, and monitoring script.Take the dog on a lead - do not carry her. Perl references.Getting more log information from the Apache http web serverA demonstration of how many Python facilities work togetherResearch is exciting. But should routine be automated?Python for loops - applying a temporary second name to the same objectMelksham to become a part of Trowbridge?Light bulbs