Late-binding of function defaults (was Re: What is a function parameter =[] for?)

Steven D'Aprano steve at pearwood.info
Thu Nov 26 20:43:05 EST 2015


On Thu, 26 Nov 2015 10:23 pm, Marko Rauhamaa wrote:

> Chris Angelico <rosuav at gmail.com>:
> 
>> On Thu, Nov 26, 2015 at 9:54 PM, Marko Rauhamaa <marko at pacujo.net> wrote:
>>>
>>>    >>> hash([])
>>>    Traceback (most recent call last):
>>>      File "<stdin>", line 1, in <module>
>>>    TypeError: unhashable type: 'list'
>>>
>>> Annoying.
>>
>> Yes, it's really annoying that you get an immediate exception instead
>> of unpredictably getting bizarre failures that depend on the exact
>> bucket sizes and dict size and so on. It's such a pain to get told
>> exactly where the problem is.
> 
> The problem is that lists don't have __hash__ and __eq__ defined.


I'm pretty sure that lists have __eq__ defined :-P



>> Python tends to assume that programmers are intelligent people who are
>> prepared to fix their mistakes.
> 
> It's not letting me in the case of list.


Less whining, more programming:

class MyList(list):
    def __hash__(self):
        return 1


There you go, problem solved. New problems are your responsibility:


py> a = MyList([1, 2])
py> d = {a: "spam"}
py> d[MyList([1, 2])]  # Looks good so far.
'spam'
py> a.append(3)
py> d[MyList([1, 2])]  # Where did my key go?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: [1, 2]


py> b = MyList([1, 3])
py> d[b] = "eggs"
py> d[MyList([1, 3])]  # So far so good.
'eggs'
py> b[1] -= 1
py> b.append(3)
py> d[b]  # What?
'spam'


All I can say is, this would be an absolutely awesome feature for Python to
have, if you were being paid by the hour for debugging.



-- 
Steven




More information about the Python-list mailing list