[MERGE] remove has_key() usage
John Arbash Meinel
john at arbash-meinel.com
Tue Aug 29 22:54:41 BST 2006
Brian Harring wrote:
> On Tue, Aug 29, 2006 at 04:35:05PM -0500, John Arbash Meinel wrote:
>> Robey Pointer wrote:
>>> I've posted a branch at:
>>>
>>> http://www.lag.net/~robey/code/bzr.dev.no_has_key/
>>>
>>> which removes the remaining usage of [dict].has_key() that I found in
>>> bzr.dev. No new features were added, no bugs were fixed, and nothing
>>> really was accomplished except housekeeping. It just kept me busy on
>>> the train. :)
>>>
>>> Patch attached for review.
>>>
>>> robey
>>>
>>>
>> Is there any particular reason why 'x in foo' is better than
>> 'foo.has_key(x)'? I suppose 'in' is supported by more than just dicts
>> (sets, lists, etc).
>> Just wondering if there is some python advice that I haven't heard of.
>
> 1) slightly faster
> $ python -m timeit -s 'd=dict([(x,None) for x in xrange(1000)]);' 'd.has_key(500)'
> 1000000 loops, best of 3: 1.48 usec per loop
> $ python -m timeit -s 'd=dict([(x,None) for x in xrange(1000)]);' '500 in d'
> 1000000 loops, best of 3: 1.02 usec per loop
>
> Why that's faster, as far as I know it comes down to the fact the
> interpretter does the __contains__ getattr rather then the python code
> triggering it itself; might just be that it is less opcodes; either
> way, consistantly faster in my experience.
Actually, I think this is exactly it. When a class is defined it must
have __len__ and __contains__ defined, they can't be added later. They
can be changed later, but at one point I was writing a wrapper class
that did:
class Foo(object):
def __init__(self, wrap):
self._wrap = wrap
self.__len__ == wrap.__len__
...
And then if I tried to call 'len(foo)' it would tell me it was an
unsized object. I had to change it to:
def __len__(self):
return len(self._wrap)
So you are probably right. dict.has_key() has to look up the 'has_key'
function in the __dict__ member, in case you overwrite it. While 'foo in
dict' actually uses a compiled member, that has to exist at the time of
class definition.
>
> 2) it relies on the general containment protocol rather then a dict
> specific method; code can work with any sequence without having to be
> changed if it relies on __contains__ instead of the dict specific
> containment method.
Sure.
>
> Most sane code just sets has_key for dicts to
> def has_key(self, key):
> return key in self
>
> rather then maintaining anyways. :)
>
> ~brian
>
:)
So overall, I think I'm happy with Robey's changes. +1 from me.
John
=:->
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 254 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20060829/c2d0a588/attachment.pgp
More information about the bazaar
mailing list