Modify subclassed string in place

2024/11/15 13:03:07

I've got the following string subclass:

class S(str):def conc(self, next_val, delimiter = ' '):"""Concatenate values to an existing string"""if not next_val is None:self = self + delimiter + next_valreturn self

I expect this to work as follows:

>>> x = S("My")
>>> x.conc("name")
'My name'
>>> x
'My name'

Instead I get this:

>>> x = S("My")
>>> x.conc("name")
'My name'
>>> x
'My'

Is there a way to modify the string in place? I think this gets into the difference between mutable and immutable strings. Subclassing seems to be the correct way to treat strings as mutable objects (at least according to the python docs) but I think I'm missing some key piece in my implementation.

Answer

You can't do what you're asking, because strings are immutable. The docs tell you to wrap the str class; that is, to make a class with an attribute which is the current value of the "mutable string". This exists in the standard library of Python 2.x as UserString.MutableString (but is gone in Python 3); it's pretty easy to write, though:

class MutableString(object):def __init__(self, value):self.value = valuedef conc(self, value, delim=' '):self.value = "{self.value}{delim}{value}".format(**locals())def __str__(self):return self.value

however, a better plan is to use a StringIO. In fact, you can get pretty close to the functionality that you wanted by subclassing StringIO (note that you need to use the pure Python version not the C version to do this, and that it's an old-style class so you can't use super). This is neater, faster, and altogether IMO more elegant.

>>> from StringIO import StringIO as sIO
>>> class DelimitedStringIO(sIO):
...     def __init__(self, initial, *args, **kwargs):
...             sIO.__init__(self, *args, **kwargs)
...             self.write(initial)
...
...     def conc(self, value, delim=" "):
...             self.write(delim)
...             self.write(value)
...
...     def __str__(self):
...             return self.getvalue()
...
>>> x = DelimitedStringIO("Hello")
>>> x.conc("Alice")
>>> x.conc("Bob", delim=", ")
>>> x.conc("Charlie", delim=", and ")
>>> print x
Hello Alice, Bob, and Charlie

You can override __repr__ if you want x to look even more like a string, but this is bad practice, since where possible __repr__ is meant to return a description in Python of the object.

https://en.xdnf.cn/q/72115.html

Related Q&A

sum numpy ndarray with 3d array along a given axis 1

I have an numpy ndarray with shape (2,3,3),for example:array([[[ 1, 2, 3],[ 4, 5, 6],[12, 34, 90]],[[ 4, 5, 6],[ 2, 5, 6],[ 7, 3, 4]]])I am getting lost in np.sum(above ndarray ,axis=1), why …

Get the number of nonzero elements in a numpy array?

Is it possible to get the length of the nonzero elements in a numpy array without iterating over the array or masking the array. Speed is the main goal of calculating the length.Essentially, something…

Pytest on Python Tools for visual studio

Can debug python tests which are using pytest library on visual studio 2010 ? I added the -m pytest on the Interpreter arguments but the breakpoints are not hit, I can only run the test script without…

Python Paramiko directory walk over SFTP

How to do os.walk() but on another computer through SSH? The problem is that os.walk() executes on a local machine and I want to ssh to another host, walk through a directory and generate MD5 hashes f…

Python 2.7 32-bit install on Win 7: No registry keys?

I have downloaded the Python 2.7.2 Windows x86 32-bit MSI from python.org and installed it on a 64-bit Windows 7 system. Everything works (at least the command-line interpreter starts and runs), but t…

i18n with jinja2 + GAE

I googled for a GAE + jinja i18n example but could not find it. Can anyone provide a link or working example?My effort uses the django translations and I dont know if this is the recommend way of doin…

Interpolating one time series onto another in pandas

I have one set of values measured at regular times. Say:import pandas as pd import numpy as np rng = pd.date_range(2013-01-01, periods=12, freq=H) data = pd.Series(np.random.randn(len(rng)), index=rng)…

Reference class variable in a comprehension of another class variable

This may be a simple question, but Im having trouble making a unique search for it. I have a class that defines a static dictionary, then attempts to define a subset of that dictionary, also statically…

Pyspark module not found

Im trying to execute a simple Pyspark job in Yarn. This is the code:from pyspark import SparkConf, SparkContextconf = (SparkConf().setMaster("yarn-client").setAppName("HDFS Filter")…

Multiple windows in PyQt4?

Ive just begun using pyqt4. I followed a tutorial (http://zetcode.com/tutorials/pyqt4/) One thing that puzzles me is this part:def main():app = QtGui.QApplication(sys.argv)ex = GUI()sys.exit(app.exec()…