エラーの説明
投稿で提供されているコードを考えると、 AttributeError を受け取る必要があるため、 KeyError を取得する方法が実際にはわかりません (str(other,name)
が意図されたタイプミスであったと仮定しますstr(other.name)
)。AttributeError は、ルックアップ中のキーがオブジェクトではなく int/long である__eq__
ため、self の名前を other の名前と比較するときにメソッドから発生します。hash(str('abc'))
Test
__hash__
dict でキーを検索する場合、実行される最初の操作は、キーのメソッドを使用してキーのハッシュを取得することです。次に、このハッシュの値が dict に存在する場合__eq__
、キーのメソッドが呼び出され、見つかった値とキーを比較します。これは、同じハッシュを持つオブジェクトが dict に格納されている場合 (オープン アドレス指定によって)、正しいオブジェクトが取得されるようにするためです。平均して、このルックアップはまだ O(1) です。
hash(str('abc'))
これを 1 ステップずつ見ていくと、とのハッシュはobj
同じです。では、文字列のハッシュとしてTest
定義します。__hash__
でルックアップを実行するとtest_Dict[hash(str('abc'))]
、実際にはハッシュのハッシュがルックアップされますが、int のハッシュ自体が python であるため、これは問題ありません。
定義したメソッドに従ってこれら 2 つの値__eq__
を比較すると、オブジェクトの名前が比較されますが、比較対象の値は int ( hash(str('abc'))
) であり、プロパティを持たないname
ため、AttributeError が発生します。
解決
hash()
まず、このキーはメソッドの 2 番目の引数としても渡されるため、実際の dict 検索を実行するときに呼び出す必要はありません (すべきではありません) __eq__
。そう
test_Dict[hash(str('abc'))].name
なるべき
test_Dict[str('abc')].name
あるいは単に
test_Dict['abc'].name
文字列リテラルの呼び出しstr()
はあまり意味がないためです。
次に、比較対象__eq__
のオブジェクトのタイプを考慮に入れるようにメソッドを編集する必要があります。インスタンスをキーとしてother
同じ dict に保存されるものに応じて、これにはさまざまなオプションがあります。Test
インスタンスを他の のみ (またはプロパティを持つ任意のオブジェクト)Test
と一緒にディクショナリに格納する場合は、現在持っているものを保持できます。Test
name
def __eq__(self, other):
return str(self.name) == str(other.name)
辞書で比較している他のすべてのキーがタイプTest
であり、name
.
ディクショナリ内のインスタンスを文字列のみと混合する場合は、Python では文字列にプロパティTest
がないため、比較するオブジェクトが文字列かどうかを確認する必要があります。name
def __eq__(self, other):
if isinstance(other, str):
return str(self.name) == other
return str(self.name) == str(other.name)
Test
とその他のタイプのオブジェクトを組み合わせてキーとして使用する場合は、other
オブジェクトname
に比較対象の があるかどうかを確認する必要があります。
def __eq__(self, other):
if hasattr(other, "name"):
return str(self.name) == str(other.name)
return self.name == other # Or some other logic since here since I don't know how you want to handle other types of classes.
私は最後の2つのファンではありません.Pythonでのダックタイピングに反対するようなものですが、人生には常に例外があります.