Efficient Python means Python with Style

Efficient Python means lower cost in development and maintenance of
Software. Python programs written in a good style are easier to
develop, easier to read and cheaper to maintain.
Because they are easier to maintain, they are easier and cheaper
to extend and are therefore more up to date and more useful.

I will describe what I mean with a good style and explain basic command line parsing.

The basic structure of a Python program consists of the ‘hash bang’ notation
in the first line and the encoding string in the second line.
Next will be the actual code.

#!/usr/bin/env python
# -*- coding: utf8 -*-

print "Hello Beautiful World"

For a simple program as this, where is really no need for something else.
Running

$ ./demo1.py
"Hello Beautiful World"
$

does just what you expect.

To make our little example more useful, we start to add some procedural structure:

#!/usr/bin/env python
# -*- coding: utf8 -*-
def hello ():
    print "Hello Beautiful World"

if __name__ == '__main__':
    hello ()

We encapsulate the actual program logic in a function called ‘hello’.
This function is called only when the program file called demo2.py is executed by the Python interpreter directly, like this

$ ./demo2.py
"Hello Beautiful World"
$

Let’s see what really happens inside. Change the code like this:

#!/usr/bin/env python
# -*- coding: utf8 -*-

def hello ():
    print "Hello Beautiful World"

print "__name__:", __name__

if __name__ == '__main__':
    print "this is __main__"
    hello ()

and run it from the command line:

$ ./demo2.py
__name__: __main__
this is __main__
$

So the variable __name__ somehow automatically received the value ‘__main__’ by the Python interpreter.

The purpose of this behavior is easy to see, when we run our sample program in a different context:

$ python
>>> from demo2 import *
>>> __name__: demo2
>>>

Now the magic variable __name__ has the name of the module ‘demo2’ and the next to last line is starting to make sense: the program itself can distinguish between being run as a program by itself or being imported as a module.

To use the functionality of the program in the module context, we need to call the function named ‘hello’.

>>> hello()
Hello Beautiful World
>>>

To sum up, we’ve learned, that we can use a single program file both as a self contained program and as an importable module.

Now, let’s give our program some more structure:

#!/usr/bin/env python
# -*- coding: utf8 -*-

class App (object):
    def __init__ (self):
        self.text = "Hello Beautiful World"

    def run (self):
        print self.text

if __name__ == '__main__':
    app = App ()
    app.run ()

We’ve created an application class called ‘App’ to serve as a container. The class ‘App’ defines two methods, one called ‘__init__’ and ‘run’.

In ‘__init__’ initialization of the object takes place. In ‘run’ the actual work of printing the message is done.

When the program is run as a stand alone application, the object ‘app’ is created from the class, with the ‘__init__’-method called by Python. In the next line, the ‘run’ method is executed to serve the actual purpose of this program.

Running the program:

$ ./demo3.py
Hello Beautiful World
$

does exactly what we expected.

Using this sample in a module context allows us to use object creation and and execution separately:

python
>>> from demo3 import *
>>> app = App()
>>> app.run()
Hello Beautiful World
>>>

We can create multiple App-Objects and use them independently:

>>> app2 = App()
>>> app2.run()
Hello Beautiful World
>>> app
<demo3.App object at 0x7f62817b0550>
>>> app2
<demo3.App object at 0x7f62817b0610>
>>>

To show, the two app instances are really distinct objects we just need to look at where respective object addresses above.

Advantages of the this object oriented encapsulation will show up in larger programs. We laid the foundation for further extension.

 

Leave a Reply

Your email address will not be published. Required fields are marked *