[Python-Dev] Intricacies of calling __eq__
Terry Reedy
tjreedy at udel.edu
Wed Mar 19 02:29:05 CET 2014
On 3/18/2014 9:09 PM, Steven D'Aprano wrote:
> Currently, the code:
>
> if key in dict:
> return dict[key]
>
>
> performs two dictionary lookups. If you read the code, you can see the
> two lookups: "key in dict" performs a lookup, and "dict[key]" performs a
> lookup.
The doc says that
@deco
def f(): pass
is equivalent to
def f(): pass
f = deco(f)
That clearly implies two assignments to the containing namespace. But
CPython only does one. It actually does something like
def <internal function reference>(): pass
f = deco(<internal function reference>)
This can be detected by defining deco to have the side-effect of
checking the local namespace for a binding to 'f' (actually, <internal
function reference>.__name__) and reporting via print() before
returning. When someone did detect the difference and filed a bug
report, Guido declared that the difference did not matter and that the
current behavior is close enough to meeting the as-if rule.
Optimizing away a dict lookup strikes me as similar to optimizing away a
namespace binding, which is typically a dict setting, which would
involve a dict lookup. In fact, I imagine that your test class with a
__eq__ method that reports calls would be an alternate way to detect the
@deco optimization.
--
Terry Jan Reedy
More information about the Python-Dev
mailing list