Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not assign `cls.__hash__ = id`?

I would have hoped this works (in Python 3.6),

class A:
    __hash__ = id
A().__hash__()

but I get

TypeError: id() takes exactly one argument (0 given)

Surprisingly,

def my_id(self):
    return id(self)
class A:
    __hash__ = my_id
A().__hash__()

works as hoped.

like image 579
Bananach Avatar asked Jun 05 '20 10:06

Bananach


People also ask

What does __ hash __ do in Python?

Call __hash__ on the key to compute the hash of the key. If the key is not hashable raise a TypeError. Store (hash_value, key, value) in an array at location hash_value % len(array) . If the array requires resizing, re-use the previously computed hash_value s to re-insert all previously stored values.

What is the difference between id and hash in Python?

Unequal objects may have the same hash values. Equal objects need to have the same id values. Whenever obj1 is obj2 is called, the id values of both objects is compared, not their hash values.


1 Answers

id is of type builtin_function_or_method (it's a function that's built into the runtime - ), which for practical reasons (optimisation mainly) doesn't implement the descriptor protocol as a python function would, so A().__hash__ resolves to the id function itself, not to a method object wrapping the function.

You'll observe the same behaviour with most builtin functions FWIW:

>>> type(len)
<class 'builtin_function_or_method'>
>>> len.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'
>>> 
>>> type(all)
<class 'builtin_function_or_method'>
>>> all.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'
>>> type(abs)
<class 'builtin_function_or_method'>
>>> abs.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'
>>> type(isinstance)
<class 'builtin_function_or_method'>
>>> isinstance.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'

etc...

like image 200
bruno desthuilliers Avatar answered Sep 22 '22 03:09

bruno desthuilliers