我有以下字符串子类:
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_val
return self
我希望这项工作如下:
>>> x = S("My")
>>> x.conc("name")
'My name'
>>> x
'My name'
相反,我得到了这个:
>>> x = S("My")
>>> x.conc("name")
'My name'
>>> x
'My'
有没有办法修改字符串?我认为这会影响可变字符串和不可变字符串之间的区别。子类化似乎是将字符串视为可变对象的正确方法(至少根据python docs),但我认为我在实现中缺少一些关键部分。
答案 0 :(得分:4)
你不能做你所要求的,因为字符串是不可变的。文档告诉你 wrap str
类;也就是说,创建一个具有属性的类,该属性是“可变字符串”的当前值。它存在于Python 2.x的标准库中UserString.MutableString
(但在Python 3中已经消失了);但是写起来很容易:
class MutableString(object):
def __init__(self, value):
self.value = value
def conc(self, value, delim=' '):
self.value = "{self.value}{delim}{value}".format(**locals())
def __str__(self):
return self.value
但是,更好的计划是使用StringIO
。实际上,通过子类化StringIO
,您可以非常接近所需的功能(请注意,您需要使用纯Python版本而非C版本才能执行此操作,并且它是一个旧式类,因此您不能使用super
)。这更整洁,更快,而且IMO更加优雅。
>>> 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
如果您希望__repr__
看起来更像字符串,则可以覆盖x
,但这是不好的做法,因为在可能的情况下__repr__
意味着返回Python中的描述对象。
答案 1 :(得分:3)
第self = self + delimiter + next_val
行正在创建新变量self
并将self + delimiter + next_val
的结果分配给此。要实现您的目标,您需要将操作直接应用于self
变量。但由于字符串是不可变的,所以你不能这样做。这正是所有str
方法返回新字符串而不是修改它们操作的字符串的原因。
很抱歉,你不能做你想要完成的事情。
答案 2 :(得分:1)
Python字符串(以及从它们继承的任何内容)都是不可变的。
在UserString模块中有一个名为MutableString的类可能会执行您想要的操作。
如果您正在使用python的最新版本(如在2.7 / 3.1版本中),您也可以查看bytearray,尽管它有自己的一组限制和怪癖。
答案 3 :(得分:0)
没有可变的字符串。有字节/字节数组和单字符字符串列表,您可以修改它们然后变成一个字符串。如果你想模仿一个“可变字符串”,你必须在一个私有字段中保留一个字符串,替换它,否则假装你是那个字符串(这可能是MutableString
所做的)。但要注意:这将是非常低效的,并且可能不需要。此外,您不能总是使用可变字符串代替不可变字符串(例如,作为dict键)。为什么你认为你需要一个可变的字符串?我们其他人(以及Java和.NET人员)相处得很好。
您的conc
不起作用,因为Python没有传递引用。 self = ...
不会更改当前对象,它只会覆盖局部变量(self.member = ...
)做但是,因为这是修改某些字典的方法调用。)
答案 4 :(得分:0)
以下是您要执行的操作的实现:
class S(object):
def __init__(self, val=""):
self.data = val;
def conc(self, next_val, delimiter = ' '):
if not next_val is None:
self.data = self.data + delimiter + next_val
return self
def __repr__(self):
return self.data
您可以使用更多方法扩展此类。