-2

I am trying to create a class in python that will have all the str characteristics , but will also be mutable.

Example:

>>> a = mutableString("My string")
>>> print a +"c"
"My stringc"
>>> a[0] = "a"
>>> a
"ay string"

How is it possible by inheriting from str?

Edit: What i Have done so far is:

class mutableString(object):
    def __init__(self, string):
        self.string = string
    def __setitem__(self, item, value):
        self.string = self.string[:item] + value + self.string[item + len(value):]
        print type(self.string)
    def __repr__(self):
        return self.string

In this case, i can do:

a = mutableString("aaa")
a[2] = "b"
print a
#prints aab

but I can't do:

print a + "c"
#unsupported operand type(s) for +: 'mutableString' and 'str'

So, what I'm trying to do is creating a class that would keep str characteristics, but allow me to setitem.

  • `str` will still be immutable even if you inherit from it. I don't think that inheriting from `str` is going to help you. – khelwood Jul 08 '15 at 11:48
  • 5
    Inheriting from list and overwriting functions to be more stringlike seems a better approach. – SuperBiasedMan Jul 08 '15 at 11:49
  • 1
    And why will you want to do that? – styvane Jul 08 '15 at 11:49
  • 1
    You must first understand the *mutable-immutable* concept. [This question](http://stackoverflow.com/questions/8056130/immutable-vs-mutable-types-python) will help you some. But basically, mutable objects use their memory address reference and update the stored object on that memory block when the value of the object changes. When an immutable object changes, a new memory block is allocated and *updated* result stored there and object starts to use new memory block, abandoning the old one. And **strings are immutable** and any class that derived from str will be immutable too. – Mp0int Jul 08 '15 at 11:58
  • possible duplicate of [Mutable strings in Python](http://stackoverflow.com/questions/10572624/mutable-strings-in-python) – elegent Jul 08 '15 at 12:27

5 Answers5

0

I believe this will give the functionality that you want:

    class mutableString():
        def __init__(self,string):
            self.string = list(string)
        def concat(self,pos,notherstr): #pos is so you can concatenate where you want!
            self.string[pos] = self.string[pos] + notherstr
            return "".join(self.string) 
        def changestr(self,pos,notherstr):
            self.string[pos] = notherstr
            return "".join(self.string)

You then can call your class, of course I have not handled errors that could pop up (such as putting in a pos that is larger than the length of the list) so I will leave that to you.

Now you could say:

    a = mutableString("Hello")
    a.concat(4,'a')  #Output: "Helloa"
    a.changestr(4,'d') #"Helld"
jfish003
  • 1,232
  • 8
  • 12
0

not comprehensive, but here is a more complete mutable string class using the same setitem method. I threw in the subtraction operator for fun. :) you can continue with the same pattern of creating a function you need that is in the string class, and calling that function on self.string and returning that wrapped in the mystring() class to return the mutable string class rather than the python string class.
string class

the output of the program is: '' 'foobar' 'foobarfoobarfoobarfoobar' 'foobarfoobarfoo' 'foofoofoo' 'foofoof' 'foobarfoof' 'boobarfoof'

have fun!

0

First, you would need to override __add__ so that a + "c" works:

def __add__(self, other):
    if isinstance(other, mutableString):
        return mutableString(self.string + other.string)
    elif isinstance(other, str):
        return mutableString(self.string + other)
    else:
        raise NotImplemented

However, you also need to implement __radd__ so that "c" + a will work as well; str.__add__("c", a) will raise NotImplemented, triggering a call to mutableString.__radd__(a, "c").

def __radd__(self, other):
    return self + other  # which simply invokes mutableString.__add__

Essentially, you'll need to override everything str supports in order to provide a similar API. You are correctly not inheriting from str to begin with, because that won't let you suddenly treat the value as mutable.

chepner
  • 497,756
  • 71
  • 530
  • 681
0

Instead of defining functions like concat and all, You can add the special method _add_ to the class.

class Str(object):
def __init__(self, string):
    self.string = string
def __setitem__(self, item, value):
    if item<0: item=item+len(self.string)
    self.string = self.string[:item] + value + self.string[item + len(value):]
def __add__(self,value,/):
    return self.string + value
def __repr__(self):
    return self.string

I have modified the code of https://stackoverflow.com/users/4218896/jfish003 in two places

  • Firstly the _setitem_ method so that negative indices work
  • Secondly I have wrote the _add_ method to concatenate strings
-1

What you want already exists as a Python builtin: it's the bytearray class. https://docs.python.org/2/library/functions.html#bytearray

Max Noel
  • 8,810
  • 1
  • 27
  • 35