[Python-ideas] comparison of operator.itemgetter objects

Jim Jewett jimjjewett at gmail.com
Thu Apr 5 18:33:19 CEST 2012


On Mon, Apr 2, 2012 at 4:30 AM, Max Moroz <maxmoroz at gmail.com> wrote:

> I think that comparing sort keys for equality works well in many useful
> cases:

> (a) Named function. These compare as equal only if they are identical. If
> lhs and rhs were initialized with distinct named functions, I would argue
> that the programmer did not intend them to be compatible for the purpose of
> binary operations, even if they happen to be identical in behavior (e.g., if
> both functions return back the argument passed to them). In a well-designed
> program, there is no need to duplicate the named function definition if the
> two are expected to always have the same behavior.

It may be that they were created as inner functions, and the reason to
duplicate was either to avoid creating the function at all unless it
was needed, or to keep the smaller function's logic near where it was
needed.

In a sense, you are already recognizing this by asking that different
but equivalent functions produced by the itemgetter factor compare
equal.

> (c) itemgetter. Suppose a programmer passed `itemgetter('name')` as the sort
> key argument to the sorted data structure's constructor. The resulting data
> structures would seem incompatible for the purposes of binary operations.
> This is likely to be confusing and undesirable.

operator.attrgetter seems similar.

> (d) lambda functions. Similarly, suppose a programmer passed `lambda x : -x`
> as the sort key argument to the sorted data structure's constructor. Since
> two lambda functions are not identical, they would compare as unequal.

> It seems to be very easy to address the undesirable behavior described in
> (c): add method __eq__() to operator.itemgetter, which would compare the
> list of arguments received at initialization.

Agreed.  I think this may just be a case of someone assuming YAGNI,
but if you do need it, and submit a patch, it should be OK.

> It is far harder to address the undesirable behavior described in (d). If it
> can be addressed at all, it would have to done in the sorted data structure
> implementation, since I don't think anyone would want lambda function
> comparison behavior to change. So for the purposes of this discussion, I
> ignore case (d).

Why not?  If you really care about identity for a lambda function,
then you should be using "is", and if you don't, then equivalent
behavior should be enough.

I would support a change to function.__eq__ (which would fall through
to lambda) such that they were equal if they had the same bytecode,
signature, and execution context (defaults, globals, etc).  I would
also support making functions and methods orderable, for more easily
replicated reprs.  I'm not volunteering to write the patch, at least
today.

> Is this a reasonable idea? Is it useful enough to be considered? Are there
> any downsides I didn't think of?

Caring that two functions are identical is probably even less common
than sticking a function in a dict, and the "nope, these are not
equal" case would get a bit slower.

-jJ



More information about the Python-ideas mailing list