[Python-de] Nicht-Hashbare Elemente schnell zugreifen

Andreas Pakulat apaku at gmx.de
Mon Jun 26 13:55:54 CEST 2006


On 26.06.06 13:11:02, Stefan Behnel wrote:
> Andreas Pakulat wrote:
> > ich hab hier ein etwas verzwicktes Problem. Ich moechte in ein
> > Dictionary mit nicht-hashbaren Objekte indizieren, prinzipiell zwar
> > machbar mit id(), aber die Objekte sind aus einer C-Library (also
> > gewrappte C-Objekte) und werden immer wieder neu erzeugt. Ich bekomme
> > also fuer dasselbe Objekt aus der Library 2 verschiedene Python Objekte.
> > Deswegen hatte ich nun schon einen Vergleichsoperator fuer diese Objekte
> > geschrieben (auf C-Level kann man die Teile vergleichen).
> 
> Spricht was dagegen, auch noch __hash__ zu implementieren? Hab das gerade mal
> für lxml gemacht, basierend auf der Adresse des C Objektes. Funktioniert
> wunderbar:
> 
> cdef class Element:
>     cdef xmlNode* _c_node
>     def __hash__(self):
>         return python.PyLong_FromVoidPtr(self._c_node)

Hmm, mal schauen, sollte nicht zu schwer sein, das mit dem Vergleich war
ja auch viel einfacher als zuerst gedacht...

> In lxml ist sowas weniger wichtig, da ohnehin während der Lebensdauer
> von Element Objekten immer das selbe Objekt zurückgeliefert wird.
> Solange sie also in einer Hash-Tabelle sind, wirst du auch immer das
> selbe Objekt (und damit den selben Hash-Key) von lxml bekommen. Nach
> dem, was du schreibst, scheint libxml2 diese Optimierung  nicht zu
> haben.

Das Problem mit den libxml2 bindings ist IMHO dass sie jedesmal neue
Python-Objekte generieren wenn man auf z.B. die children-Achse zugreift.
Auch bei XPath Ausdruecken gibts immer neue Python-Objekte. Deswegen ja
der == Operator, damit sowas wie

nodes = EvaluateXPath()

for node in nodes:
	if node in self.treenodes:
	  highlight(self.treenodes[node])

funktioniert. 

Andreas

-- 
Today's weirdness is tomorrow's reason why.
		-- Hunter S. Thompson