1

私はたくさんのFileオブジェクトを持っていFolderます。各フォルダにlistはファイルがあります。ここで、特定のファイルがどのフォルダーにあるかを検索したいことがあります。すべてのフォルダーとファイルをトラバースしたくないので、検索dictファイル -> フォルダーを作成します。

folder = Folder()
myfile = File()
folder_lookup = {}

# This is pseudocode, I don't actually reach into the Folder
# object, but have an appropriate method
folder.files.append(myfile)
folder_lookup[myfile] = folder

問題は、ファイルが変更可能なオブジェクトであることです。私のアプリケーションは事実に基づいて構築されています。それらのプロパティを変更すると、それに応じて GUI が通知され、更新されます。もちろん、変更可能なオブジェクトを辞書に入れることはできません。だから私が最初に試みたのは、基本的に現在のコンテンツに基づいてハッシュを生成することです:

def __hash__(self):
    return hash((self.title, ...))

オブジェクトのコンテンツが変更されると、そのハッシュ (したがってその ID) が変更され、すべてが台無しになるため、これはもちろん機能しませんでした。私が必要としているのは、内容が変わってもアイデンティティを保持するオブジェクトです。__hash__returnを作成したりid(self)、オーバーライドしたりなど、さまざまなことを試し__eq__ましたが、満足のいく解決策は見つかりませんでした。複雑なことの 1 つは、構造全体がピッケル可能でなければならないことです。つまり、ピッケルid時に変更される可能性があるため、作成時に保存する必要があるということです。

したがって、基本的には、オブジェクトに関連するデータをすばやく検索するために、オブジェクトの ID (状態ではなく) を使用したいと考えています。私は実際に私の問題に対する本当に素晴らしいPythonicの回避策を見つけました。これはすぐに投稿するかもしれませんが、他の誰かが解決策を考え出すかどうかを知りたいです.

4

2 に答える 2

0

OK、誰もが非常に明白な回避策に気付きました (思い付くのに数日かかりました)。属性を付けFileて、それがどのフォルダーにあるかを示します (心配しないでください。それは私がしたことでもあります)。

しかし、私は間違った仮定の下で働いていたことが判明しました。変更可能なオブジェクトをキーとして使用することは想定されていませんが、だからといって使用できないわけではありません (悪魔のような笑い声)! のデフォルトの実装は__hash__、おそらくオブジェクトのアドレスから派生した一意の値を返します。この値は時間的に一定です。そして、デフォルト__eq__はオブジェクト ID の同じ概念に従います。

したがって、変更可能なオブジェクトをdictに入れることができ、それらは期待どおりに機能します(値ではなくインスタンスに基づく同等性を期待する場合)。

参照: Python で変更可能なオブジェクトを辞書キーとして使用できます。これは許されませんか?

オブジェクトをピクルス化/ピクルス化解除していたため、もちろんハッシュが変更されたため、問題が発生していました。コンストラクターで一意の ID を生成し、それを使用して等価性を確保し、これを克服するためにハッシュを導出することができます。

(好奇心のために、なぜそのような「インスタンスIDに基づく検索」口述が必要なのかについて:私は一種の「オブジェクトデータベース」で実験してきました.純粋なpythonオブジェクトがあり、それらをリスト/コンテナに入れ、そしてより高速なルックアップや複雑なクエリなどのために、属性にインデックスを定義できます. 外部キー (1:n 関係) の場合はコンテナーを使用できますが、バックリンクの場合は、変更したくない場合は何か巧妙なものを考え出す必要があります. n側のオブジェクト)。

于 2013-07-26T16:33:47.100 に答える
0

私はこれを書いて汚いと感じました。ファイルの属性としてフォルダーを配置するだけです。

class dodgy(list):
    def __init__(self, title):
        self.title = title
        super(list, self).__init__()
        self.store = type("store", (object,), {"blanket" : self})
    def __hash__(self):
        return hash(self.store)

innocent_d = {}
dodge_1 = dodgy("dodge_1")
dodge_2 = dodgy("dodge_2")
innocent_d[dodge_1] = dodge_1.title
innocent_d[dodge_2] = dodge_2.title

print innocent_d[dodge_1]
dodge_1.extend(range(5))
dodge_1.title = "oh no"
print innocent_d[dodge_1]
于 2013-07-26T13:58:11.550 に答える