Print
Python Cookbook

Cooking with Python
Seven Tasty Recipes for Programmers

07/11/2002

by Robin Parma, Alex Martelli, Scott David Daniels, Ben Wolfson, Nick Perkins, Anurag Uniya, Tim Keating, Rael Dornfest and Jeremy Hylton, authors of the Python Cookbook

1. Simple Tests Using Exceptions

Usually Python is straightforward, but there are a few unexpected exceptions.
Credits: Robin Parma

Problem

You want to know if the contents of a string represent an integer, which is not quite the same thing as checking whether the string contains only digits.

Solution

# try/except is generally the best approach to such problems:

def IsInt(str):
	"""Is the given string an integer?"""
	try:int(str)
	except ValueError:return 0
	else:return 1

Discussion

Use exceptions to perform simple tests that are otherwise laborious. If you want to know if the contents of a string represent an integer, just try to convert it. That's what IsInt() does. The try/except mechanism catches the exception raised when the string cannot be converted to an int, turning it into a harmless return 0. The else clause, which runs only when no exception is raised in the try clause, gives a return 1 when the string is OK.

Don't be misled by the word "exception," or by what is considered good style in different programming languages. Relying on exceptions and try/except is a useful Pythonic idiom.

2. Constants in Python

Liberal Python lets you rebind any variable; yet, there is an instance where you can protect your variables.
Credits: Alex Martelli

Problem

You need to define module-level variables that client-code cannot accidentally rebind, such as "named constants."

Solution

# Needs Python 2.1 or better. Put in const.py...:

class _Constants:
	class ConstError(TypeError): pass
	def __setattr__(self, name, value):
		if self.__dict__.has_key(name):
			raise self.ConstError, "Can't rebind const(%s)"%name
		self.__dict__[name ] = value
	def __delattr__(self, name):
		if self.__dict__.has_key(name):
			raise self.ConstError, "Can't unbind	const(%s)"%name
		raise NameError, name
import sys
sys.modules[__name__] = _Constants()

# now any client-code can:
import const
# and bind an attribute ONCE:
const.magic =23
# but NOT re-bind it:
# const.magic =88 # would raise const.ConstError

Discussion

In Python, any variable can be re-bound at will. Modules don't let you define special methods, such as an instance's __setattr__, to stop attribute re-binding. An easy solution (in Python 2.1 and up) is to use an instance as "module."

Python 2.1 and up no longer forces entries in sys.modules to be module objects. You can install an instance object there and take advantage of its attribute-access special methods while still having client-code get at it with import somename. You might see this as a more Pythonic "Singleton"-ish idiom (but also see "Singleton? We don't need no stinkin' Singleton: the Borg non-pattern"). Note that this recipe ensures a constant binding for a given name, not an object's immutability, which is quite a different issue.

Pages: 1, 2, 3

Next Pagearrow