ハッシュ可能性と可変性の関係について:
有用であるためには、ハッシュ実装は次の特性を満たす必要があります。
等しいを使用して比較する2つのオブジェクトのハッシュ値は等しく==
なければなりません。
ハッシュ値は時間の経過とともに変化しない場合があります。
これらの2つのプロパティは、インスタンスを比較するときにハッシュ可能なクラスが可変プロパティを考慮に入れることができないことを意味し、インスタンスを比較するときに可変プロパティを考慮に入れるクラスはハッシュ可能ではないことを意味します。不変クラスは、比較に影響を与えることなくハッシュ可能にすることができます。
すべての組み込みの可変型はハッシュ可能ではなく、すべての不変の組み込み型はハッシュ可能です。これは主に上記の観察結果です。
ユーザー定義クラスは、デフォルトでオブジェクトIDに基づいて比較を定義しid()
、ハッシュとして使用します。これらは変更可能ですが、インスタンスを比較するときに変更可能なデータは考慮されないため、ハッシュ可能にすることができます。
クラスをハッシュ可能にしても、魔法のように不変になるわけではありません。逆に、元の比較演算子を維持しながら辞書を合理的な方法でハッシュ可能にするには、最初に辞書を不変にする必要があります。
編集:あなたのアップデートに関して:
グローバルな不変辞書に相当するものを提供する方法はいくつかあります。
collections.namedtuple()
代わりにインスタンスを使用してください。
読み取り専用プロパティを持つユーザー定義クラスを使用します。
私は通常、次のようなものを使用します。
_my_global_dict = {"a": 42, "b": 7}
def request_value(key):
return _my_global_dict[key]
先頭の下線で、_my_global_dict
アプリケーションコードに触れないようにする実装の詳細であることを明確にします。このコードでは、ディクショナリ値が変更可能なオブジェクトである場合でも、ディクショナリ値を変更できることに注意してください。この問題は、必要に応じて値のcopy.copy()
sまたはsを返すことで解決できます。copy.deepcopy()