Container May 27, 2006
A general container of attributes, with support for pretty printing. Very useful for debugging, etc.
Used extensively in Construct to represent parsed objects.
Code
#
# module Container.py
#
def recursion_lock ( retval , lock_name = "____recursion_lock" ):
def decorator ( func ):
def wrapper ( self , * args , ** kw ):
if getattr ( self , lock_name , False ):
return retval
setattr ( self , lock_name , True )
try :
return func ( self , * args , ** kw )
finally :
setattr ( self , lock_name , False )
return wrapper
return decorator
class Container ( object ):
def __init__ ( self , ** kw ):
self . __dict__ . update ( kw )
@ recursion_lock ( "<...>" )
def __repr__ ( self ):
attrs = sorted ( "%s = %r" % ( k , v ) for k , v in self . __dict__ . iteritems () if not k . startswith ( "_" ))
return "%s(%s)" % ( self . __class__ . __name__ , ", " . join ( attrs ))
@ recursion_lock ( "<...>" )
def __str__ ( self , nesting = 1 ):
attrs = []
indentation = " " * nesting
for k , v in self . __dict__ . iteritems ():
if not k . startswith ( "_" ):
text = [ indentation , k , " = " ]
if isinstance ( v , Container ):
text . append ( v . __str__ ( nesting + 1 ))
else :
text . append ( repr ( v ))
attrs . append ( "" . join ( text ))
attrs . sort ()
attrs . insert ( 0 , self . __class__ . __name__ + ":" )
return " \n " . join ( attrs )
Example
>>> c = Container(a=1, b="baaa")
>>> c # calls repr()
Container(a = 1, b = 'baaa')
>>> print c # calls str()
Container:
a = 1
b = 'baaa'
>>> c.c = 1.23
>>> print c
Container:
a = 1
b = 'baaa'
c = 1.23
>>> c.d = Container(e = 6, f = "g")
>>> c
Container(a = 1, b = 'baaa', c = 1.23, d = Container(e = 6, f = 'g'))
>>> print c
Container:
a = 1
b = 'baaa'
c = 1.23
d = Container:
e = 6
f = 'g'
>>> c.h = c # recursive referencing
>>> c
Container(a = 1, b = 'baaa', c = 1.23, d = Container(e = 6, f = 'g'), h = <...>)
>>> print c
Container:
a = 1
b = 'baaa'
c = 1.23
d = Container:
e = 6
f = 'g'
h = <...>
>>>