[Patches] [ python-Patches-941881 ] PEP309 Partial implementation

SourceForge.net noreply at sourceforge.net
Sat Feb 19 21:38:09 CET 2005


Patches item #941881, was opened at 2004-04-25 12:05
Message generated for change (Comment added) made by bediviere
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=941881&group_id=5470

Category: Library (Lib)
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: Hye-Shik Chang (perky)
Assigned to: Nobody/Anonymous (nobody)
Summary: PEP309 Partial implementation

Initial Comment:
This patch implements functional module which is
introduced by PEP309. It has only 'partial' function as
its member in this stage.

Unittest code is copied and modified slightly from
Patch #931010 by Peter Harris.

----------------------------------------------------------------------

Comment By: Steven Bethard (bediviere)
Date: 2005-02-19 13:38

Message:
Logged In: YES 
user_id=945502

It might be nice if partial objects were usable as
instancemethods, like functions are.  Note the following
behavior with the current patch:

>>> import functional
>>> class C(object):
...     pass
...
>>> def func(self, arg):
...     return arg
...
>>> for item in ['a', 'b', 'c']:
...     setattr(C, item, functional.partial(func, item))
...
>>> C().a()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: func() takes exactly 2 arguments (1 given)

If functional.partial was instead defined like:

class partial(object):
    def __init__(*args, **kwargs):
        self = args[0]
        try:
            self.func = args[1]
        except IndexError:
            raise TypeError('expected 2 or more arguments,
got ' %
                            len(args))
        self.obj = ()
        self.args = args[2:]
        self.kwargs = kwargs
    def __call__(self, *args, **kwargs):
        if kwargs and self.kwargs:
            d = self.kwargs.copy()
            d.update(kwargs)
        else:
            d = kwargs or self.kwargs
        return self.func(*(self.obj + self.args + args), **d)
    def __get__(self, obj, type=None):
        if obj is None:
            return self
        result = partial(self.func, *self.args, **self.kwargs)
        result.obj = (obj,)
        return result

where an appropriate __get__ method is provided, then
partial objects behave properly when set as attributes to a
class:

py> def test():
...     class C(object):
...         pass
...     def func(self, arg):
...         return arg
...     for item in ['a', 'b', 'c']:
...         setattr(C, item, functional.partial(func, item))
...     c = C()
...     return c.a(), c.b(), c.c()
... 
py> test()
('a', 'b', 'c')

----------------------------------------------------------------------

Comment By: Nick Coghlan (ncoghlan)
Date: 2004-08-10 18:11

Message:
Logged In: YES 
user_id=1038590

I have tested this patch on Windows, and it passes its own
test suite, without affecting any other tests.

However, PCBuild\pythoncore.vcproj & PC\config.c require
modification to allow Python to pick up the new module
correctly.

Patch #1006948 created with the needed changes (also removes
unneeded ODBC references from pythoncore.vcproj as I am
using the free MS toolkits to build here)

My patch definitely needs to be checked by someone with a
copy of Vis Studio 2003!

----------------------------------------------------------------------

Comment By: Paul Moore (pmoore)
Date: 2004-08-03 14:23

Message:
Logged In: YES 
user_id=113328

OK, a real need beats my theoretical worries :-) Consider me
convinced.

----------------------------------------------------------------------

Comment By: Bob Ippolito (etrepum)
Date: 2004-05-17 22:05

Message:
Logged In: YES 
user_id=139309

I would use partial in situations where speed can matter (imap, 
commonly used event handlers, etc.), so a fast C implementation would 
be nice to have.

----------------------------------------------------------------------

Comment By: Paul Moore (pmoore)
Date: 2004-04-27 02:03

Message:
Logged In: YES 
user_id=113328

Yes, that looks like a significant speed improvement :-) I was 
basing my assumptions on the comments made in the PEP. 
Sorry.

But I still wonder if having the implementation in Python 
wouldn't be better from a maintenance point of view. (As well 
as all the arguments about usefulness as sample code, ability 
to backport, etc etc, that have come up on python-dev 
regarding moving other Python library modules into C...).

----------------------------------------------------------------------

Comment By: Hye-Shik Chang (perky)
Date: 2004-04-26 20:05

Message:
Logged In: YES 
user_id=55188

Python-version (function) ...   1.19    2.69
Python-version (class) ...      2.61    2.38
C-version ...   0.50    0.37
(former value is for 100000 instanciations and latter is for
100000 calls.)

And, C version have a facility that changing attributes after
the instantiation that is supported by class version only.

----------------------------------------------------------------------

Comment By: Paul Moore (pmoore)
Date: 2004-04-26 13:30

Message:
Logged In: YES 
user_id=113328

Why implement this in C? I can't imagine that the
performance improvement will be that significant. A pure
Python module in the standard library seems to me to be a
far better idea. As the PEP says, "the case for a built-in
coded in C is not very strong". And a Python module is good
self-documentation.

I prefer the function version suggested in the PEP (credited
to Carl Banks) over the class-based one. You need to take a
little care to avoid capturing argument names:

    def partial(*args, **kwds):
        def callit(*moreargs, **morekwds):
            kw = kwds.copy()
            kw.update(morekwds)
            return args[0](*(args[1:]+moreargs), **kw)
        return callit

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=941881&group_id=5470


More information about the Patches mailing list