473,836 Members | 1,598 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A Comparison of Python Class Objects and Init Files for Program Configuration

A Comparison of Python Class Objects and Init Files for Program
Configuration
=============== =============== =============== =============== =============== ==

Terrence Brannon
ba*****@metaper l.com
http://www.livingcosmos.org/Members/...iguration/view

Abstract
--------

Init files serve as a convenient mini-language for configuring
applications. The advantages of such a mini-language are

* non-technical people can edit them.
* program behavior can be configured without modifying the source

The author `has always been suspicious of mini-languages
<http://perlmonks.org/?node_id=428053 >`_, initially in the context of
dynamic HTML generation.

This document provides a comparison of two approaches to program
development, the use of `a popular Python mini-language
<http://www.voidspace.o rg.uk/python/configobj.html> `_ and the use of
`Python class objects <http://www.mired.org/home/mwm/config.html>`_.

The Problem Space
-----------------

I work for a company that takes data in various formats (e.g., CSV,
XML, Filemaker) and integrates them all into our database. The 30 or
so scripts that did this were written in Perl. I was told to rewrite
them and elected to use Python.

The Initial Rewrite Using Init Files
------------------------------------

In the initial version using config files, I used a generic config
file and specialized/overwrote its values with a local one::

gconfig = ConfigObj("../generic.ini")
cnf = ConfigObj("loca l.ini")
cnf.merge(gconf ig)

I then proceeded to login to an FTP server and check for a certain
file and download it if it existed::

host = ftputil.FTPHost (cnf['ke_ftp']['host'],
cnf['ke_ftp']['user'],
cnf['ke_ftp']['pass'])

host.chdir(cnf['ke_ftp']['cwd'])
found = ""
for f in host.listdir(ho st.curdir):
if f.endswith( cnf['ke_ftp']['filepattern'] ):
found = f
print "Downloadin g", found
host.download(f , f, 'b')

if found == "":
print "No file with pattern", cnf['ke_ftp']['filepattern'], "on
server"
sys.exit()

Now lets see the object-oriented configuration
----------------------------------------------

Instead of generic and specialized config files, one would initially
think of using inheritance when going for an OO approach. However,
each program can get configuration information from a number of
places. As a result, HAS-A will work better than IS-A in this case::

class config(object):

# best to use has-a because we need config info from all over the
place
import data.config.ke

ke = data.config.ke. ftp()
ke.user = 'dmsdatasystems '
ke.password = 'sredna?'
ke.cwd = 'DMS/companies'
ke.filepattern = 'companies.csv. gz'

import data.config.sna p
snap = data.config.sna p.ftp()
"""
import data.storage
storage = data.storage.lo gic()
print dir(storage)
sys.exit()"""

class proc(object):

def __init__(self):
self.cnf = config()

def fetch_file(self ):
host = ftputil.FTPHost (self.cnf.ke.ho st, self.cnf.ke.use r,
self.cnf.ke.pas sword)
host.chdir(self .cnf.ke.cwd)

self.downloaded _file = ""
for f in host.listdir(ho st.curdir):
if f.endswith( self.cnf.ke.fil epattern ):
self.downloaded _file = f
print "Downloadin g", f
host.download(f , f, 'b')
print "Downloaded ", f

if self.downloaded _file == "":
print "No file with pattern", self.cnf.ke.fil epattern, "on",
self.cnf.ke.hos t
sys.exit()


Evaluation
==========

Appearance
----------

Accessing object attributes, IMHO, is much cleaner looking. Compare::

config['munger']['outfile']

with::

config.munger.o utfile
One takes less characters to type and lacks the noisy quote marks
(that's one of the things I miss from Perl hashes - the ability to
index into hashes using bare words without quotes).

Power
-----

A mini-language is a moving target. They tend to grow and grow over
time, adding more and more ad hoc semantics and peculiarities. I'm on
the ConfigObj mailing list and they are currently discussing how to
handle multi-line config values. In Python, one simply needs to break
out """ and you are done. This epitomizes why I prefer the shortcut
of library over mini-language. The library has the full power of a
widely used, widely debugged language while the mini-language has a
smaller user community and less man hours of development behind it.

Learning Curve
--------------

Again, once you learn Python, you can use it for configuration as well
as programming. And Python is a very readable, clean and regular
language - it doesn't look very different from a configuration
language.

The merits of studying the syntax and semantics of a configuration
language can possibly outweigh the benefits.
Maintenance
-----------

It is harder to hire people with a good background in object
oriented programming than it is to find a "scripter".

By taking the
object-oriented route with this program, I have made it harder for
people to maintain my code in one sense but easier in another. A
well-decomposed OO program, especially in a language as elegant and
powerful as Python, is truly something to enjoy. To those versed in
such technologies, it is probably easier and more fun to extend such a
program.

On the other hand, a config file and a script would allow a person
with average scripting skills, perhaps even with no Python background,
to make small edits and extensions with little difficulty.

Manipulation
------------

Indexing into a hash with strings is a bit more easy to parameterize
than accessing object attributes. For example, to make a tuple of a
list of hash values, you can do this::

[a , b , c] = map ( lambda k: config[k], "key1 key2 key3".split() )

To get attributes from an object is slightly wordier::

[a , b , c] = map ( lambda k: getattr(cnf, k), "key1 key2 key3".split()
)

Self-documenting problem decomposition
--------------------------------------

One thing I really like about the OO approach is that it provided an
affordance to break down the steps of the processing into separate
methods. This leads to self-documenting code::

if __name__ == '__main__':

p = proc()

p.fetch_file()
p.unzip_file()
p.munge_data()
p.snap_upload()
p.archive_zipdi r()

In contrast, when I wrote the program using config files, I had
comments interspersed in the linear stream-of-consciousness script to
break out sections::

#
--------------------------------------------------------------------------
# Fetch DMS file from KE FTP
#
--------------------------------------------------------------------------

Now, granted, one _could_ create bunch of methods and decompose the
problem in that way, it's just that structuring a program with one
or more mini-languages as opposed to object-oriented libraries does
not provide as much of an affordance for such an approach.

This Document
=============

This document was prepared using `reStructuredTe xt
<http://docutils.source forge.net/rst.html>`_.

Sep 12 '06 #1
0 2515

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
5486
by: Haoyu Zhang | last post by:
Dear Friends, Python assignment is a reference assignment. However, I really can't explain the difference in the following example. When the object is a list, the assignment seems to be a reference. However, when the object is a number, the story is so different. I don't understantd for what reason Python deals with them differently. The example is as follows: >>> a = >>> b = a
8
1548
by: Ali El Dada | last post by:
hi all: in python, when a class, say Father, has a member that itself is an instance of another class, say Child, an instance of Father actually only has a reference to a Child, not the Child object itself, right? because i know that in eiffel they give the programmer the 2 options, the second being implemented with an additional keyword (expanded) so as the eiffel documentation says,
8
2539
by: jose luis fernandez diaz | last post by:
Hi, I am reading Stroustrup's book 'C++ Programming Language'. In the 10.4.9 section (Nonlocal Store) he says: "A variable defined outside any function (that is global, namespace, and class static variables) is initializated (constructed) before main is invoked . . ." .. . .
2
2671
by: RickMuller | last post by:
I really appreciate the ease that the distutils make distributing Python modules. However, I have a question about using them to distribute non-Python (i.e. text) data files that support Python modules. Currently when I have data of this type, I parse it into python objects and make a python module from it. In other words, given a data file like % cat grocery_list.txt eggs spam
25
7760
by: Xah Lee | last post by:
Python Doc Problem Example: gzip Xah Lee, 20050831 Today i need to use Python to compress/decompress gzip files. Since i've read the official Python tutorial 8 months ago, have spent 30 minutes with Python 3 times a week since, have 14 years of computing experience, 8 years in mathematical computing and 4 years in unix admin and perl, i have quickly found the official doc: http://python.org/doc/2.4.1/lib/module-gzip.html
10
2216
by: John Henry | last post by:
Hi all, I have a need to create a Python script on the fly from another Python program and then execute the script so created. Do I need to invoke Python through os.spawnl or is there a better way? Thanks, -- John
37
2827
by: spam.noam | last post by:
Hello, Guido has decided, in python-dev, that in Py3K the id-based order comparisons will be dropped. This means that, for example, "{} < " will raise a TypeError instead of the current behaviour, which is returning a value which is, really, id({}) < id(). He also said that default equality comparison will continue to be identity-based. This means that x == y will never raise an exception, as is the situation is now. Here's his reason:
0
153
by: =?UTF-8?B?TmlscyBPbGl2ZXIgS3LDtmdlcg==?= | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, I don't think the global interpreter lock is what you need ... read here for reference: http://docs.python.org/api/threads.html
0
9671
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10852
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10553
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10255
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7793
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6980
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5829
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4021
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3116
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.