1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 | 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 = <...>
>>>
|