[Python-Dev] Possible patch for functools partial (original) (raw)

VanL van.lindberg at gmail.com
Fri May 7 21:53:01 CEST 2010


On 5/7/2010 12:41 PM, Steven D'Aprano wrote:

Now, if I write

def f1(x,y): return x+y def f2(x,y): return x+y I don't expect f1==f2 to be True, even though f1 and f2 behave in exactly the same way, and indeed it is not.

This is not what I am getting after; these (IMO) should compare unequal. I took a fairly conservative line, testing for identity of functions and equality of arguments when converted to a normal form:

def __eq__(self, other):
    try:
        return ((self.func == other.func) and
                    (self.args == other.args) and
                    (self.keywords == other.keywords))
    except AttributeError:
        return False

def __hash__(self):
    if self.keywords:
        sorted_keys = sorted(self.keywords.keys())
        values = [self.keywords[k] for k in sorted_keys]
        kwhash = tuple(sorted_keys + values)
    else:
        kwhash = None
    return hash(tuple((self.func, self.args, kwhash)))

It may be slightly controversial that I read out all the keys and values and convert them to a normal form for the hash. This is both to get around hashing issues (keywords is a dict, even though it is read-only) and to allow for a dict-like object to be provided as an argument (which happens in my application sometimes).

The repr is slightly long, too, but it was designed to support (weakly) the idea that obj == exec(repr(obj)). Its not necessary, but I always like it when that is true.

def __repr__(self):
    if self.args: argstr = '*%s' % repr(tuple(self.args))
    else: argstr = ''
    if self.keywords: kwstr = '**%s' % self.keywords
    else: kwstr = ''
    if argstr and kwstr: argstr += ', '
    classname = self.__class__.__name__
    funcname = self.func.__name__
    if argstr or kwstr: funcname += ', '
    return '%s(%s%s%s)' % (classname, funcname, argstr, kwstr)

I make no effort to look for functional equality between two different functions. too many side effects could go off trying to make that work, and it would still be only inconsistently right. (IIRC, doing it completely is NP-hard.)

Thanks,

Van



More information about the Python-Dev mailing list