2

カスタム オブジェクトとして記述されたアプリケーションのリストがあるとします。使用可能なアプリケーションのプールのように機能する 1 つのリストを作成できるように、元のアプリケーション リストのディープ コピーを作成することにしました。アプリケーションを割り当てるには、プールのサブセットをランダムに選択し、元のリストでそれらのアプリケーションを見つけて、それらの情報を更新できるようにします。次に、割り当てられたアプリケーションがプールから削除されます。しかし、何らかの理由で、元のリストにアプリケーションが見つかりません。

list1 = [App1,App2,App3,App4,App5]
pool = copy.deepcopy(list1)
num_apps = rand.randrange(0,5)
random.shuffle(pool)
selected_apps = copy.deepcopy(pool[:num_apps])
for app in selected_apps:
    locn = list1.index(app)
    print locn

上記のコードは実際には、selected_apps 内の項目が見つからないという ValueError を返します。エラーは、Python にネイティブでないオブジェクトを含むリストのディープ コピーを作成しているという事実によるものですか?

4

1 に答える 1

0

使用list.indexする場合は、比較演算子 ( ==) を使用してアイテムが同じかどうかを確認し、ドキュメントから__eq__メソッドを使用します。

ユーザー定義のクラスには、デフォルトでメソッド__eq__()とメソッドがあります。__hash__()それらを使用すると、すべてのオブジェクトは等しくなく (それ自体を除く) 、それと の両方を意味するようx.__hash__()な適切な値を返します。x == yx is yhash(x) == hash(y)

これは次の方法で実証できます。

>>> class A(object):
...     def __init__(self):
...         self.x = 0
... 
>>> a = A()
>>> a.x = 5
>>> b = a
>>> b == a
True
>>> c = copy.deepcopy(a)
>>> c == a
False

CPythonid()では、オブジェクトのメモリ アドレスを返すため__eq__、ID が一致する場合は true を返します。

>>> id(a) 
140389541757224
>>> id(b)
140389541757224
>>> id(c)
140389541757336

__eq__したがって、メソッドとを実装するだけです__ne__

比較演算子間に暗黙の関係はありません。の真は、それが偽x==yであることを意味しません。x!=yしたがって、 を定義するときは、演算子が期待どおりに動作するように__eq__()定義する必要があります。__ne__()

>>> class A(object):
...     def __init__(self):
...         self.x = 0
...     def __eq__(self, o):
...         return self.x == o.x
...     def __ne__(self, o):
...         return self.x != o.x
... 
>>> a = A()
>>> a.x = 5
>>> b = a
>>> c = copy.deepcopy(a)
>>> d = A()
>>> d.x = 4
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a == d
False

これにも注意してください:

クラスが__eq__()メソッドを定義しない場合は、__hash__()操作も定義しないでください。定義していても定義して__eq__()いない__hash__()場合、そのインスタンスはハッシュ可能なコレクションのアイテムとして使用できません

于 2015-05-13T20:16:52.833 に答える