web-dev-qa-db-ja.com

python文字列とタプルが不変になるのはなぜですか?

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

49
user186477

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

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

http://effbot.org/pyfaq/why-are-python-strings-immutable.htm

32
Nasir

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

_a = "abc"
_

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

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

_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」に変更します。 、したがって、dictには「zbc」と「zbc」の2つのキーがあります。

この奇妙さの解決策の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() 関数はオブジェクトのメモリアドレスを返します)

74
dbr

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

10
Mark Ransom

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

4
Philipp

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

Pythonに不変の文字列がある理由の質問に対する私の答えは、Python作成者のGuidovan Rossumがそのように望んでいたためです。彼には、防御するファンの軍団がいます。彼らの死にゆく息へのその恣意的な決定。

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

3
phileas fogg

長所:パフォーマンス

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

3
easement