6

次の文字列サブクラスがあります。

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のドキュメントによると)が、実装にいくつかの重要な部分が欠けていると思います。

4

5 に答える 5

4

文字列は不変であるため、求めていることを実行できません。ドキュメントでは、クラスをラップするように指示されています。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(これを行うには、C バージョンではなく純粋な Python バージョンを使用する必要があることに注意してください。これは古いスタイルのクラスであるため、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__たい場合はオーバーライドできますが、可能であればオブジェクトの Python での説明を返すことを意図しているため、これは悪い習慣です。x__repr__

于 2010-12-23T16:01:31.490 に答える
3

行は新しい変数self = self + delimiter + next_valを作成し、これに結果を代入しています。目的を達成するには、操作を変数に直接適用する必要があります。しかし、文字列は不変であるため、これを行うことはできません。これがまさに、すべての s メソッドが操作対象の文字列を変更するのではなく、新しい文字列を返す理由です。selfself + delimiter + next_valselfstr

申し訳ありませんが、達成しようとしていることができません。

于 2010-12-23T15:57:17.967 に答える
1

Python 文字列 (およびそれらから継承されたもの) は不変です。

あなたが望むことをするかもしれない UserString モジュールに MutableString と呼ばれるクラスがあります。

最近の (2.7/3.1 のような) バージョンの python を使用している場合は、bytearray を調べることもできますが、独自の制限と癖があります。

于 2010-12-23T16:02:38.770 に答える
0

変更可能な文字列はありません。バイト/バイト配列と 1 文字の文字列のリストがあり、これらを変更して文字列に変換できます。「変更可能な文字列」をエミュレートしたい場合は、文字列をプライベートフィールドに保持し、それを置き換えて、それ以外の場合はその文字列であるふりをする必要があります (これはおそらくそうですMutableString)。ただし、注意してください。これは非常に非効率的であり、おそらく必要ありません。また、変更できない文字列の代わりに常に変更可能な文字列を使用できるとは限りません (たとえば、dict キーとして)。なぜ変更可能な文字列が必要だと思いますか? 私たちの残りの部分 (および Java と .NET の人たち) は、なくても問題なくやっています。

Pythonには参照渡しがないため、機能しませconcん。self = ...現在のオブジェクトを変更せず、ローカル変数を上書きするだけです(self.member = ...機能しますが、これは辞書を変更するメソッド呼び出しであるためです)。

于 2010-12-23T16:00:39.597 に答える
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

より多くのメソッドを使用してこのクラスを拡張できます。

于 2010-12-23T16:30:42.080 に答える