Hooks, aspect-oriented programming, and design by contract
Luigi Ballabio
ballabio at mac.com
Tue Jan 22 07:28:47 EST 2002
Hi,
maybe I'm just reinventing the wheel, but I just noted that Alex's
Aspecter function can easily be twitched to enforce some kind of design by
contract (which of course can be considered an aspect).
Here's my first shot at it. Corrections and improvements are much welcome.
Bye,
Luigi
def AddInvariant(cls, predicate, message=None):
base_getattribute = cls.__getattribute__
message = message or "class invariant violation"
def __getattribute__(self, name):
attr = base_getattribute(self, name)
if callable(attr):
attr = wrap_predicate(predicate, message, self, attr)
return attr
cls.__getattribute__ = __getattribute__
def wrap_predicate(predicate, message, self, method):
def wrapper(*args):
result = method(*args)
if not predicate(self):
raise Exception, message
return result
return wrapper
# Let's use it now
# Silly example class
class Account(object):
def __init__(self):
self.amount = 0.0
def deposit(self,amount):
self.amount += amount
def withdraw(self,amount):
self.amount -= amount
# We don't give any credit to anybody
AddInvariant(Account, lambda self: self.amount >= 0.0, "negative balance")
savings = Account()
savings.deposit(100)
savings.withdraw(50) # this works
savings.withdraw(70) # this raises "negative balance"
More information about the Python-list
mailing list