Re: wx.Colour - not hashable in Phoenix/Py3
Douglas Thor <[email protected]>
| Newsgroups | gmane.comp.python.wxpython.devel |
|---|---|
| Message-ID | <[email protected]> |
Until either SIP adds __hash__ or another solution is found, here's a
workaround:
In ..\site-packages\wx\core.py, add the following code around line 557,
where the rest of the Colour class is defined:
def _Colour___hash__(self):
return hash(tuple(self.Get()))
Colour.__hash__ = _Colour___hash__
del _Colour___hash__
I know that the top of core.py says to not edit the file, but I couldn't
help myself :-D.
I've done a tiny bit of testing, only verifying that
1. hash(wx.Colour(1,1,1,255)) does not raise a TypeError
2. hash(wx.Colour(1,1,1,255)) == hash((1,1,1,255))
3. My project actually runs.
Robin, making this change won't cause the world to end, will it? I know
that it will get overwritten the next time SIP generates core.py, but that
I can live with.
Thanks,
On Wednesday, March 11, 2015 at 6:30:11 PM UTC-7, Robin Dunn wrote:
>
>
> From the docs for both Python2 and Python3:
> """
> An object is hashable if it has a hash value which never changes during
> its lifetime (it needs a __hash__() method), and can be compared to
> other objects (it needs an __eq__() method). Hashable objects which
> compare equal must have the same hash value.
>
> Hashability makes an object usable as a dictionary key and a set member,
> because these data structures use the hash value internally.
>
> All of Python’s immutable built-in objects are hashable, while non
> mutable containers (such as lists or dictionaries) are not. Objects
> which are instances of user-defined classes are hashable by default;
> they all compare unequal (except with themselves), and their hash value
> is derived from their id().
> """
>
> SIP doesn't add a default __hash__ in either build, it just relies on
> the default Python behavior. In Python2 that seems to be a hash value
> derived from the object's ID. In other words, you could think of it
> like this:
>
> class HashableColour(wx.Colour):
> def __hash__(self):
> return do_something(id(self))
>
> Based on the above text I would have expected the same from Python3, but
> perhaps the definition of "user-defined classes" was changed to not
> include extension types. Or maybe that doc needs updating.
>
> Either way, I prefer the Python3 way because basing a default hash value
> on the id() means that you must use the same instance of the key to
> fetch the value again, you can't simply use a new key with the same
> value. For example, in Python2:
>
> >>> c1 = wx.Colour(1,2,3)
> >>> c2 = wx.Colour(1,2,3)
> >>>
> >>> d = {c1: 'one', c2: 'two'}
> >>> d[c1]
> 'one'
> >>> d[c2]
> 'two'
> >>> d[wx.Colour(1,2,3)]
> Traceback (most recent call last):
> File "<input>", line 1, in <module>
> KeyError: wx.Colour(1, 2, 3, 255)
> >>>
>
> In Python3 Python makes you actually think about what makes sense for
> your class's hash values, it doesn't just give you some mindless
> substandard thing for free. For wx.Colour I might choose something like:
>
> class HashableColour(wx.Colour):
> def __hash__(self):
> return self.GetRGBA()
>
> or maybe even:
>
> return hash(self.Get()) # the hash of the tuple of color
> components
>
> But I suppose the real question is whether we should be adding our own
> __hash__ methods to at least some of the wrapped wxPython classes. I'll
> give that some thought.
>
>
> --
> Robin Dunn
> Software Craftsman
> http://wxPython.org
>
--
You received this message because you are subscribed to the Google Groups "wxPython-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.