[解決済み】Pythonでimmutableオブジェクトを作るには?
質問
今まで必要なかったのですが、Pythonでイミュータブルなオブジェクトを作るのは少し難しいかもしれないと思いました。あなたは、単に
__setattr__
に属性を設定することもできないからです。
__init__
. タプルをサブクラス化するのは、うまくいくコツです。
class Immutable(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
@property
def a(self):
return self[0]
@property
def b(self):
return self[1]
def __str__(self):
return "<Immutable {0}, {1}>".format(self.a, self.b)
def __setattr__(self, *ignored):
raise NotImplementedError
def __delattr__(self, *ignored):
raise NotImplementedError
しかし、その後にアクセスできるのは
a
と
b
変数を介して
self[0]
と
self[1]
というのは、迷惑な話です。
これはPure Pythonで可能ですか?もし不可能なら、C言語の拡張機能でどうすればいいのでしょうか?
(Python 3 でしか動作しない回答も可)。
更新してください。
Python 3.7では、この方法は
@dataclass
のデコレータを使用することができます。新しく受理された回答を参照してください。
どのように解決するのですか?
フローズンデータクラスの使用
Python 3.7+の場合、Pythonにインストールする前に
データクラス
を付けて
frozen=True
オプション
これは非常にpythonicで保守性の高い方法で、あなたが望むことを実現します。
というような感じになると思います。
from dataclasses import dataclass
@dataclass(frozen=True)
class Immutable:
a: Any
b: Any
として
タイプヒンティングが必要
をデータクラスのフィールドに使用しました。
からの任意の
typing
モジュール
.
Namedtupleを使用してはいけない理由
Python 3.7以前では、namedtupleがimmutableオブジェクトとして使用されているのを頻繁に見かけました。これは色々な意味で厄介なのですが、そのうちの1つは
__eq__
メソッドは、オブジェクトのクラスを考慮しません。例えば
from collections import namedtuple
ImmutableTuple = namedtuple("ImmutableTuple", ["a", "b"])
ImmutableTuple2 = namedtuple("ImmutableTuple2", ["a", "c"])
obj1 = ImmutableTuple(a=1, b=2)
obj2 = ImmutableTuple2(a=1, c=2)
obj1 == obj2 # will be True
ご覧のように、たとえ
obj1
と
obj2
は、たとえフィールド名が異なっていても、異なるものです。
obj1 == obj2
はまだ
True
. それは
__eq__
メソッドはタプルのもので、フィールドの位置を指定してその値だけを比較します。これは、特にこれらのクラスをサブクラス化している場合、エラーの大きな原因となり得ます。
関連
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み] TypeError: 'DataFrame' オブジェクトは呼び出し可能ではない
-
[解決済み】Flask ImportError: Flask という名前のモジュールがない
-
[解決済み] 関数デコレータを作成し、それらを連鎖させるには?
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Pythonで2つのリストを連結する方法は?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python 人工知能 人間学習 描画 機械学習モデル作成
-
風力制御におけるKS原理を深く理解するためのpythonアルゴリズム
-
[解決済み】ilocが「IndexError: single positional indexer is out-of-bounds」を出す。
-
[解決済み】「SyntaxError.Syntax」は何ですか?Missing parentheses in call to 'print'」はPythonでどういう意味ですか?
-
[解決済み】LogisticRegression: Pythonでsklearnを使用して、未知のラベルタイプ: '連続'を使用しています。
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】「OverflowError: Python int too large to convert to C long" on windows but not mac
-
[解決済み】 'numpy.float64' オブジェクトは反復可能ではない
-
[解決済み] スロットの使い方__?
-
[解決済み] Python (およびPython C API)。new__ と __init__ の比較