str and __setitem__

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tor Erik Soenvisen

    #1

    str and __setitem__

    Hi,

    What do I need to do to make the code below work as expected:

    class str2(str):

    def __setitem__(sel f, i, y):
    assert type(y) is str
    assert type(i) is int
    assert i < len(self)

    self = self[:i] + y + self[1+i:]


    a = str2('123')
    a[1] = '1'
    print a
    123


    The print statement should return 113

    Regards tores
  • Peter Otten

    #2
    Re: str and __setitem__

    Tor Erik Soenvisen wrote:
    What do I need to do to make the code below work as expected:
    >
    class str2(str):
    >
            def __setitem__(sel f, i, y):
                    assert type(y) is str
                    assert type(i) is int
                    assert i < len(self)
    >
                    self = self[:i] + y + self[1+i:]
    'self' is a local variable; assigning to it rebinds it but has no effect
    outside of the __setitem__() method.
    a = str2('123')
    a[1] = '1'
    print a
    123
    The print statement should return 113
    You have to start from scratch as a strings are "immutable" (once created,
    their value cannot be changed).
    >>class mutable_str(obj ect):
    .... def __init__(self, value):
    .... self._value = value
    .... def __setitem__(sel f, index, value):
    .... self._value = self._value[:index] + value +
    self._value[index+1:]
    .... def __str__(self):
    .... return self._value
    ....
    >>a = mutable_str("12 3")
    >>a[1] = "x"
    >>print a
    1x3

    Peter

    Comment

    • Steven D'Aprano

      #3
      Re: str and __setitem__

      On Thu, 25 Jan 2007 10:16:31 +0000, Tor Erik Soenvisen wrote:
      Hi,
      >
      What do I need to do to make the code below work as expected:
      Use another language *wink*

      Python strings are immutable, you can't change them in place.
      class str2(str):
      >
      def __setitem__(sel f, i, y):
      assert type(y) is str
      assert type(i) is int
      assert i < len(self)
      self = self[:i] + y + self[1+i:]
      This line rebinds a NEW string to the name "self" -- it doesn't change the
      contents of the original string. Because the name self is local to the
      method, it doesn't change references to the original string.

      Are you sure you need mutable strings?

      Here are a few different ways of getting something like a mutable string:

      * use the MutableString class from the UserString module;

      * use the mmap module;

      * use lists of characters instead of strings;


      --
      Steven

      Comment

      • bearophileHUGS@lycos.com

        #4
        Re: str and __setitem__

        Peter Otten:
        >class mutable_str(obj ect):... def __init__(self, value):
        ... self._value = value
        ... def __setitem__(sel f, index, value):
        ... self._value = self._value[:index] + value +
        self._value[index+1:]
        ... def __str__(self):
        ... return self._value
        ...>>a = mutable_str("12 3")
        >a[1] = "x"
        >print a
        For this purpose an array may be better, if you have to change it often
        and print is only once in a while:

        from array import array
        a = array("c", "123")
        a[1] = "x"
        print a

        The OP can also use a class, if some other methods are needed:

        from array import array

        class mutable_str(obj ect):
        def __init__(self, value):
        self._value = array("c", value)
        def __setitem__(sel f, index, value):
        self._value[index] = value
        def __str__(self):
        return self._value.tos tring() # this requires time

        a = mutable_str("12 3")
        a[1] = "x"
        print a

        Probably array.array can be subclassed too...

        bye,
        bearophile

        Comment

        Working...