1. ホーム
  2. python

[解決済み】なぜタプルはミュータブルアイテムを含むことができるのですか?

2022-04-18 15:12:51

質問

もしタプルが不変であるなら、なぜ不変の項目を含むことができるのですか?

リストのような変更可能な項目が変更されても、それが属するタプルは不変であることを維持するのは一見矛盾しているように見えます。

どうすれば解決するの?

それは素晴らしい質問ですね。

重要な洞察は、タプルはその中のオブジェクトがミュータブルであるかどうかを知る術がないということです。 オブジェクトをミュータブルにする唯一のものは、そのデータを変更するメソッドを持つことです。 一般に、これを検出する方法はありません。

もうひとつの洞察は、Pythonのコンテナには実際には何も入っていない、ということです。 その代わり、他のオブジェクトへの参照を保持します。 同様に、Pythonの変数は、コンパイルされた言語の変数とは異なります。その代わりに、変数名は名前空間辞書の単なるキーで、対応するオブジェクトと関連付けられています。Ned Batchhelderはこのことを彼の ブログ記事 . いずれにせよ、オブジェクトは自分の参照カウントしか知りません。それらの参照が何であるか(変数、コンテナ、またはPython内部)は知りません。

この2つの洞察を合わせると、あなたの謎が解けます(なぜ不変のタプル "containing" a list が変更されると、そのリストが変更されるように見えるのか)。 実際、タプルは変化していません(他のオブジェクトへの参照は以前と同じままです)。 タプルは変化することができませんでした(変異するメソッドを持っていなかったからです)。 リストが変更されたとき、タプルは変更の通知を受けませんでした(リストは、それが変数によって参照されているのか、タプルなのか、それとも別のリストなのかわかりません)。

タプルとは何か、どのように機能するか、そしてその使用目的について、あなたのメンタルモデルを完成させるために、この話題に触れている間に、他のいくつかの考えを紹介しましょう。

  1. タプルの特徴は、不変性よりも、その目的によって決まる。

    タプルは、Pythonが異種の情報を1つの屋根の下に集めるための方法です。 例えば s = ('www.python.org', 80) 文字列と数字を組み合わせて、ホストとポートのペアをソケットとして渡せるようにしたもので、複合オブジェクトです。 このように考えると、Mutableなコンポーネントを持つことは非常に合理的です。

  2. 不死性は、別の性質と密接に関係しています。 ハッシュアビリティ . しかし、ハッシャビリティは絶対的な性質ではありません。 タプルの構成要素の1つがハッシュ化可能でない場合、タプル全体もハッシュ化可能ではありません。例えば t = ('red', [10, 20, 30]) はハッシュ化できない。

最後の例は、文字列とリストを含む2タプルを示しています。タプル自体はミュータブルではありません(つまり、内容を変更するためのメソッドを持ちません)。 同様に、文字列はミューティングメソッドを持たないので、文字列はイミュータブルです。 リストオブジェクトはミューティングメソッドを持っているので、変更することができます。 このことは、ミュータビリティがオブジェクトの型の特性であることを示しています。あるオブジェクトはミューティングメソッドを持ち、あるオブジェクトは持ちません。 これは、オブジェクトが入れ子になっているからといって変わるものではありません。

2つのことを忘れないでください。 まず、不変性とは魔法ではなく、単に変異させるメソッドがないことです。 第二に、オブジェクトはどの変数やコンテナが自分を参照しているのかを知らない--参照カウントしか知らない。

お役に立ちましたでしょうか?)