54

文字列とタプルが不変にされた理由はわかりません。それらを不変にすることの長所と短所は何ですか?

4

6 に答える 6

84

FakeMutablePythonと呼ばれる言語を想像してみてください。ここでは、リストの割り当てなどを使用して文字列を変更できます(などmystr[0] = 'a'

a = "abc"

aこれにより、メモリアドレス0x1のメモリに、「abc」とそれを指す識別子を含むエントリが作成されます。

さて、あなたがそう言う。

b = a

これにより、識別子が作成されb、0x1の同じメモリアドレスを指します。

ここで、文字列が変更可能であり、変更した場合b

b[0] = 'z'

これにより、0x1に格納されている文字列の最初のバイトがz..に変更されます。識別子aはここを指しているため、その文字列も変更されます。

print a
print b

..両方の出力になりますzbc

これにより、非常に奇妙で予期しない動作が発生する可能性があります。辞書キーはこの良い例です:

mykey = 'abc'
mydict = {
    mykey: 123,
    'zbc': 321
}

anotherstring = mykey
anotherstring[0] = 'z'

FakeMutablePythonでは、状況はかなり奇妙になります。最初は辞書に「abc」と「zbc」の2つのキーがあります。次に、「abc」文字列を(識別子を介してanotherstring)「zbc」に変更すると、辞書には2つあります。キー、「zbc」および「zbc」..。

この奇妙さの解決策の1つは、文字列を識別子に割り当てる(または、dictキーとして使用する)たびに、文字列を0x1から0x2にコピーすることです。

これは上記を防ぎますが、200MBのメモリを必要とする文字列がある場合はどうなりますか?

a = "really, really long string [...]"
b = a

突然、スクリプトが400MBのメモリを消費しますか?これはあまり良くありません。

変更するまで、同じメモリアドレスを指すとどうなりますか?コピーオンライト。問題は、これを行うのは非常に複雑になる可能性があるということです。

これが不変性の出番です。.replace()メモリから新しいアドレスに文字列をコピーするメソッドを要求する代わりに、それを変更して返します。すべての文字列を不変にするだけなので、関数は返す新しい文字列を作成する必要があります。これは次のコードを説明しています:

a = "abc"
b = a.replace("a", "z")

そして、次のように証明されています。

>>> a = 'abc'
>>> b = a
>>> id(a) == id(b)
True
>>> b = b.replace("a", "z")
>>> id(a) == id(b)
False

id()関数はオブジェクトのメモリアドレスを返します)

于 2009-10-27T18:56:17.780 に答える
34

1つはパフォーマンスです。文字列が不変であることを知っていると、構築時に簡単にレイアウトできます。固定された不変のストレージ要件です。これは、タプルとリストを区別する理由の1つでもあります。これにより、実装は文字列オブジェクトを安全に再利用することもできます。たとえば、CPythonの実装では、1文字の文字列に事前に割り当てられたオブジェクトを使用し、通常、コンテンツを変更しない文字列操作の元の文字列を返します。

もう1つは、Pythonの文字列は、数値として「要素」と見なされることです。アクティビティの量によって値8が他の値に変更されることはなく、Pythonでは、アクティビティの量によって文字列「8」が他の値に変更されることはありません。

https://web.archive.org/web/20201031092707/http://effbot.org/pyfaq/why-are-python-strings-immutable.htm

于 2009-10-08T15:51:29.473 に答える
9

それらを不変にすることの大きな利点の1つは、辞書のキーとして使用できることです。キーの変更が許可された場合、辞書で使用される内部データ構造がかなり混乱することになると確信しています。

于 2009-10-08T15:52:09.537 に答える
4

不変型は、概念的には可変型よりもはるかに単純です。たとえば、C++のようにコピーコンストラクタやconst-correctnessをいじる必要はありません。不変の型が多いほど、言語は簡単になります。したがって、最も簡単な言語は、グローバル状態のない純粋関数言語です(ラムダ計算はチューリングマシンよりもはるかに簡単で、同様に強力であるため)が、多くの人はこれを評価していないようです。

于 2010-07-02T12:16:34.777 に答える
3

長所:パフォーマンス

短所:可変変数を変更することはできません。

于 2009-10-08T15:51:34.280 に答える
3

Perlには可変の文字列があり、問題なく機能しているようです。上記は、恣意的な設計決定のために多くの手を振って合理化するように思われます。

Pythonに不変の文字列がある理由についての私の答えは、Pythonの作成者であるGuido van Rossumがそのように望んでいたためです。彼には今、その恣意的な決定を彼らの息を切らして擁護するファンの軍団がいます。

Perlに不変の文字列がない理由と、不変の文字列の概念がどれほどひどいのか、Perlに不変の文字列がないのはなぜこれまでで最高のアイデア(TM)なのか、という同様の質問を投げかけることができます。 。

于 2012-05-31T15:54:11.563 に答える