There's something to be said for language enforced limitations supporting encapsulation when creating an ecosystem of reusable components - something Java/C# has been great at.
An analogy is enforced immutability. Unlike Ruby, Python has immutable strings and tuples, and requires the use of immutable objects for hashmaps - a great choice for library writers, though a minor inconvenience for application programmers who want to say "trust me, i won't change this object later."
The recommended and near-universally used Ruby hash keys are immutable. Symbols are used most frequently, but even if you pass a string as a hash key it gets automatically copied and frozen. freeze is also a method on Object and can be used anywhere to make an object immutable.
Well, technically the requirement is to implement both __hash__() and one of __eq__()/__cmp__(). But Python fudges this a bit in how it handles user-defined types.
An analogy is enforced immutability. Unlike Ruby, Python has immutable strings and tuples, and requires the use of immutable objects for hashmaps - a great choice for library writers, though a minor inconvenience for application programmers who want to say "trust me, i won't change this object later."