Re: confusing doc: mutable and hashable

2012-04-29 Thread Terry Reedy

On 4/29/2012 3:57 AM, John O'Hagan wrote:


How do function objects fit into this scheme? They have __hash__, __eq__, seem
to work as dict keys and are mutable. Is it because their hash value doesn't
change?


I suspect functions use the default equality and hash based on id, which 
does not change.



Under what circumstances does an object's hash value change?


When someone has written a buggy .__hash__ method. Or perhaps if someone 
is making a non-standard, non-dict use of hash().


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-29 Thread John O'Hagan
On Sat, 28 Apr 2012 11:35:12 -0700
Chris Rebert  wrote:

[...]
> Correct. Pedantically, you can define __hash__() on mutable objects;
> it's just not very useful or sensible, so people generally don't. As
> http://docs.python.org/reference/datamodel.html#object.__hash__ states
> [emphasis added]:
> 
> "If a class defines *mutable* objects and implements a __cmp__() or
> __eq__() method, it *should not* implement __hash__(), since hashable
> collection implementations require that a object’s hash value is
> immutable (if the object’s hash value changes, it will be in the wrong
> hash bucket)."
[...]

How do function objects fit into this scheme? They have __hash__, __eq__, seem
to work as dict keys and are mutable. Is it because their hash value doesn't
change? Under what circumstances does an object's hash value change?
--
John


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-28 Thread Arnaud Delobelle
(sent from my phone)
On Apr 28, 2012 7:36 PM, "Chris Rebert"  wrote:
> Correct. Pedantically, you can define __hash__() on mutable objects;
> it's just not very useful or sensible, so people generally don't.

I find it's fine to define __hash__ on mutable objects as long as __eq__
only relies on immutable state (and then so should __hash__ of course).  A
typical example would be an object that does some caching.

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-28 Thread Terry Reedy

On 4/28/2012 2:09 PM, laymanzh...@gmail.com wrote:


In my understanding, there is no directly relation between mutable
and hashable in Python. Any class with __hash__ function is
"hashable".

According the wiki: http://en.wikipedia.org/wiki/Immutable_object

In object-oriented and functional programming, an immutable object is
an object whose state cannot be modified after it is created.[1] This
is in contrast to a mutable object, which can be modified after it is
created.

We surely can define __hash__ function in user-define class and the
instance of that class can be changed thus mutable.


The default hash is based on the immutable value of an object. If you 
base a custom hash on values that do change, it is not useful as a dict key.


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-28 Thread MRAB

On 28/04/2012 23:30, Temia Eszteri wrote:

Yes, you're right. Being mutable and hashable are orthogonal properties.
The implication
 mutable =>  non hashable
is just a design choice.

The reason for such a choice is the following. If a key-element pair K:X
is added to a container C and then K is changed by some external Python
code without letting C know of this change, C may become inconsistent.
Some containers (e.g. set) assume that K=X and just take X. Modifying X
is equivalent to modifying K in the example above.
These kinds of problems are avoided if mutable objects can't be keys.
Some containers require that keys be hashable, but since, by design,
mutable objects can't be keys, there's no reason for them to be hashable
either.

Kiuhnm


Well, if worst comes to worst and you wind up in a programming
situation where you needed to make a mutable object as a hash entry,
it's still possible to subclass the object type and have __hash__()
return the object's ID instead, right?

I can only think of a few edge cases where that could even possibly be
required though, such as membership testing for something and having a
callback associated with each set of members...


If objects x and y of the same class are mutable and you want them to
have the same hash if x == y then having __hash__() return the object's
ID is not what you want.
--
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-28 Thread Temia Eszteri
>Yes, you're right. Being mutable and hashable are orthogonal properties.
>The implication
> mutable => non hashable
>is just a design choice.
>
>The reason for such a choice is the following. If a key-element pair K:X 
>is added to a container C and then K is changed by some external Python 
>code without letting C know of this change, C may become inconsistent.
>Some containers (e.g. set) assume that K=X and just take X. Modifying X 
>is equivalent to modifying K in the example above.
>These kinds of problems are avoided if mutable objects can't be keys.
>Some containers require that keys be hashable, but since, by design, 
>mutable objects can't be keys, there's no reason for them to be hashable 
>either.
>
>Kiuhnm

Well, if worst comes to worst and you wind up in a programming
situation where you needed to make a mutable object as a hash entry,
it's still possible to subclass the object type and have __hash__()
return the object's ID instead, right?

I can only think of a few edge cases where that could even possibly be
required though, such as membership testing for something and having a
callback associated with each set of members...

~Temia
--
When on earth, do as the earthlings do.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-28 Thread Kiuhnm

On 4/28/2012 20:09, laymanzh...@gmail.com wrote:

I'm just learning Python. The python doc about mutable and hashable is 
confusing to me.

In my understanding, there is no directly relation between mutable and hashable in 
Python. Any class with __hash__ function is "hashable".

According the wiki: http://en.wikipedia.org/wiki/Immutable_object

In object-oriented and functional programming, an immutable object is an object 
whose state cannot be modified after it is created.[1] This is in contrast to a 
mutable object, which can be modified after it is created.

We surely can define __hash__ function in user-define class and the instance of 
that class can be changed thus mutable.

But following statement seems correct in practice but not technically. Any 
comments on this?

Thanks,
Andy


http://docs.python.org/py3k/library/stdtypes.html#set-types-set-frozenset:
   Since it is mutable, it has no hash value and cannot be used as either a 
dictionary key or as an element of another set.



Yes, you're right. Being mutable and hashable are orthogonal properties.
The implication
mutable => non hashable
is just a design choice.

The reason for such a choice is the following. If a key-element pair K:X 
is added to a container C and then K is changed by some external Python 
code without letting C know of this change, C may become inconsistent.
Some containers (e.g. set) assume that K=X and just take X. Modifying X 
is equivalent to modifying K in the example above.

These kinds of problems are avoided if mutable objects can't be keys.
Some containers require that keys be hashable, but since, by design, 
mutable objects can't be keys, there's no reason for them to be hashable 
either.


Kiuhnm
--
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-28 Thread Chris Rebert
On Sat, Apr 28, 2012 at 11:09 AM,   wrote:
> I'm just learning Python. The python doc about mutable and hashable is 
> confusing to me.
>
> In my understanding, there is no directly relation between mutable and 
> hashable in Python. Any class with __hash__ function is "hashable".
>
> According the wiki: http://en.wikipedia.org/wiki/Immutable_object
>
> In object-oriented and functional programming, an immutable object is an 
> object whose state cannot be modified after it is created.[1] This is in 
> contrast to a mutable object, which can be modified after it is created.
>
> We surely can define __hash__ function in user-define class and the instance 
> of that class can be changed thus mutable.
>
> But following statement seems correct in practice but not technically. Any 
> comments on this?

Correct. Pedantically, you can define __hash__() on mutable objects;
it's just not very useful or sensible, so people generally don't. As
http://docs.python.org/reference/datamodel.html#object.__hash__ states
[emphasis added]:

"If a class defines *mutable* objects and implements a __cmp__() or
__eq__() method, it *should not* implement __hash__(), since hashable
collection implementations require that a object’s hash value is
immutable (if the object’s hash value changes, it will be in the wrong
hash bucket)."

> 
> http://docs.python.org/py3k/library/stdtypes.html#set-types-set-frozenset:
>  Since it is mutable, it has no hash value and cannot be used as either a 
> dictionary key or as an element of another set.
> 

Cheers,
Chris
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: confusing doc: mutable and hashable

2012-04-28 Thread mwilson
laymanzh...@gmail.com wrote:

> I'm just learning Python. The python doc about mutable and hashable is
> confusing to me.
> 
> In my understanding, there is no directly relation between mutable and
> hashable in Python. Any class with __hash__ function is "hashable".
> 
> According the wiki: http://en.wikipedia.org/wiki/Immutable_object
> 
> In object-oriented and functional programming, an immutable object is an
> object whose state cannot be modified after it is created.[1] This is in
> contrast to a mutable object, which can be modified after it is created.
> 
> We surely can define __hash__ function in user-define class and the
> instance of that class can be changed thus mutable.
> 
> But following statement seems correct in practice but not technically. Any
> comments on this?

Wikipedia has it right.  Mutable objects are objects where significant 
attributes of the object can change value over the lifetime of the object.  
This is useful for data sharing.  If, for example, one part of your program 
knows an object by the name `a`, and another part knows the same object as 
`b` (or if they can access the object in any other distinct ways), they can 
communicate by changing values of attributes of the shared object. 

In practice, hashable means that the hashable object can be used as a key in 
a dict.  Looking up an item in a dict means that 1) the hash of the lookup 
key has to match the hash of the stored key, and 2) the lookup key has to be 
equal to the stored key according to the `==` operator.  These requirements 
are easy to meet if the keys are immutable.  Otherwise for classes you 
create, you can (if you're careful) create __hash__ and __eq__ methods to 
meet the requirements, even if significant attributes of your instances can 
change their values.

Mel.

-- 
http://mail.python.org/mailman/listinfo/python-list


confusing doc: mutable and hashable

2012-04-28 Thread laymanzheng
I'm just learning Python. The python doc about mutable and hashable is 
confusing to me. 

In my understanding, there is no directly relation between mutable and hashable 
in Python. Any class with __hash__ function is "hashable". 

According the wiki: http://en.wikipedia.org/wiki/Immutable_object

In object-oriented and functional programming, an immutable object is an object 
whose state cannot be modified after it is created.[1] This is in contrast to a 
mutable object, which can be modified after it is created.

We surely can define __hash__ function in user-define class and the instance of 
that class can be changed thus mutable. 

But following statement seems correct in practice but not technically. Any 
comments on this?

Thanks,
Andy


http://docs.python.org/py3k/library/stdtypes.html#set-types-set-frozenset:
  Since it is mutable, it has no hash value and cannot be used as either a 
dictionary key or as an element of another set.

-- 
http://mail.python.org/mailman/listinfo/python-list