"""A user-defined wrapper around string objects
Note: string objects have grown methods in Python 1.6
This module requires Python 1.6 or later.
from types
import StringTypes
__all__
= ["UserString","MutableString"]
if isinstance(seq
, StringTypes
):
elif isinstance(seq
, UserString
):
def __str__(self
): return str(self
.data
)
def __repr__(self
): return repr(self
.data
)
def __int__(self
): return int(self
.data
)
def __long__(self
): return long(self
.data
)
def __float__(self
): return float(self
.data
)
def __complex__(self
): return complex(self
.data
)
def __hash__(self
): return hash(self
.data
)
def __cmp__(self
, string
):
if isinstance(string
, UserString
):
return cmp(self
.data
, string
.data
)
return cmp(self
.data
, string
)
def __contains__(self
, char
):
def __len__(self
): return len(self
.data
)
def __getitem__(self
, index
): return self
.__class
__(self
.data
[index
])
def __getslice__(self
, start
, end
):
start
= max(start
, 0); end
= max(end
, 0)
return self
.__class
__(self
.data
[start
:end
])
def __add__(self
, other
):
if isinstance(other
, UserString
):
return self
.__class
__(self
.data
+ other
.data
)
elif isinstance(other
, StringTypes
):
return self
.__class
__(self
.data
+ other
)
return self
.__class
__(self
.data
+ str(other
))
def __radd__(self
, other
):
if isinstance(other
, StringTypes
):
return self
.__class
__(other
+ self
.data
)
return self
.__class
__(str(other
) + self
.data
)
return self
.__class
__(self
.data
*n
)
return self
.__class
__(self
.data
% args
)
# the following methods are defined in alphabetical order:
def capitalize(self
): return self
.__class
__(self
.data
.capitalize())
def center(self
, width
, *args
):
return self
.__class
__(self
.data
.center(width
, *args
))
def count(self
, sub
, start
=0, end
=sys
.maxint
):
return self
.data
.count(sub
, start
, end
)
def decode(self
, encoding
=None, errors
=None): # XXX improve this?
return self
.__class
__(self
.data
.decode(encoding
, errors
))
return self
.__class
__(self
.data
.decode(encoding
))
return self
.__class
__(self
.data
.decode())
def encode(self
, encoding
=None, errors
=None): # XXX improve this?
return self
.__class
__(self
.data
.encode(encoding
, errors
))
return self
.__class
__(self
.data
.encode(encoding
))
return self
.__class
__(self
.data
.encode())
def endswith(self
, suffix
, start
=0, end
=sys
.maxint
):
return self
.data
.endswith(suffix
, start
, end
)
def expandtabs(self
, tabsize
=8):
return self
.__class
__(self
.data
.expandtabs(tabsize
))
def find(self
, sub
, start
=0, end
=sys
.maxint
):
return self
.data
.find(sub
, start
, end
)
def index(self
, sub
, start
=0, end
=sys
.maxint
):
return self
.data
.index(sub
, start
, end
)
def isalpha(self
): return self
.data
.isalpha()
def isalnum(self
): return self
.data
.isalnum()
def isdecimal(self
): return self
.data
.isdecimal()
def isdigit(self
): return self
.data
.isdigit()
def islower(self
): return self
.data
.islower()
def isnumeric(self
): return self
.data
.isnumeric()
def isspace(self
): return self
.data
.isspace()
def istitle(self
): return self
.data
.istitle()
def isupper(self
): return self
.data
.isupper()
def join(self
, seq
): return self
.data
.join(seq
)
def ljust(self
, width
, *args
):
return self
.__class
__(self
.data
.ljust(width
, *args
))
def lower(self
): return self
.__class
__(self
.data
.lower())
def lstrip(self
, chars
=None): return self
.__class
__(self
.data
.lstrip(chars
))
def replace(self
, old
, new
, maxsplit
=-1):
return self
.__class
__(self
.data
.replace(old
, new
, maxsplit
))
def rfind(self
, sub
, start
=0, end
=sys
.maxint
):
return self
.data
.rfind(sub
, start
, end
)
def rindex(self
, sub
, start
=0, end
=sys
.maxint
):
return self
.data
.rindex(sub
, start
, end
)
def rjust(self
, width
, *args
):
return self
.__class
__(self
.data
.rjust(width
, *args
))
def rstrip(self
, chars
=None): return self
.__class
__(self
.data
.rstrip(chars
))
def split(self
, sep
=None, maxsplit
=-1):
return self
.data
.split(sep
, maxsplit
)
def rsplit(self
, sep
=None, maxsplit
=-1):
return self
.data
.rsplit(sep
, maxsplit
)
def splitlines(self
, keepends
=0): return self
.data
.splitlines(keepends
)
def startswith(self
, prefix
, start
=0, end
=sys
.maxint
):
return self
.data
.startswith(prefix
, start
, end
)
def strip(self
, chars
=None): return self
.__class
__(self
.data
.strip(chars
))
def swapcase(self
): return self
.__class
__(self
.data
.swapcase())
def title(self
): return self
.__class
__(self
.data
.title())
def translate(self
, *args
):
return self
.__class
__(self
.data
.translate(*args
))
def upper(self
): return self
.__class
__(self
.data
.upper())
def zfill(self
, width
): return self
.__class
__(self
.data
.zfill(width
))
class MutableString(UserString
):
"""mutable string objects
Python strings are immutable objects. This has the advantage, that
strings may be used as dictionary keys. If this property isn't needed
and you insist on changing string values in place instead, you may cheat
But the purpose of this class is an educational one: to prevent
people from inventing their own mutable string class derived
from UserString and than forget thereby to remove (override) the
__hash__ method inherited from UserString. This would lead to
errors that would be very hard to track down.
A faster and better solution is to rewrite your program using lists."""
def __init__(self
, string
=""):
raise TypeError, "unhashable type (it is mutable)"
def __setitem__(self
, index
, sub
):
if index
< 0 or index
>= len(self
.data
): raise IndexError
self
.data
= self
.data
[:index
] + sub
+ self
.data
[index
+1:]
def __delitem__(self
, index
):
if index
< 0 or index
>= len(self
.data
): raise IndexError
self
.data
= self
.data
[:index
] + self
.data
[index
+1:]
def __setslice__(self
, start
, end
, sub
):
start
= max(start
, 0); end
= max(end
, 0)
if isinstance(sub
, UserString
):
self
.data
= self
.data
[:start
]+sub
.data
+self
.data
[end
:]
elif isinstance(sub
, StringTypes
):
self
.data
= self
.data
[:start
]+sub
+self
.data
[end
:]
self
.data
= self
.data
[:start
]+str(sub
)+self
.data
[end
:]
def __delslice__(self
, start
, end
):
start
= max(start
, 0); end
= max(end
, 0)
self
.data
= self
.data
[:start
] + self
.data
[end
:]
return UserString(self
.data
)
def __iadd__(self
, other
):
if isinstance(other
, UserString
):
elif isinstance(other
, StringTypes
):
if __name__
== "__main__":
# execute the regression test to stdout, if called as a script:
called_in_dir
, called_as
= os
.path
.split(sys
.argv
[0])
called_as
, py
= os
.path
.splitext(called_as
)
from test
import test_support
__import__('test.test_' + called_as
.lower())