decorator module patch
Hi, to underlay my proposals with facts, I've written a simple decorator module containing at the moment only the "decorator" decorator. http://python.org/sf/1448297 It is implemented as a C extension module _decorator which contains the decorator object (modelled after the functional.partial object) and a Lib/decorator.py to allow further decorators added as Python code. Comes with docs and unit test. Please review! Cheers, Georg
Georg Brandl wrote:
Hi,
to underlay my proposals with facts, I've written a simple decorator module containing at the moment only the "decorator" decorator.
It is implemented as a C extension module _decorator which contains the decorator object (modelled after the functional.partial object) and a Lib/decorator.py to allow further decorators added as Python code.
Comes with docs and unit test.
Given that @decorator is a definition time only operation to modify a function's __name__, __doc__ and __dict__ attributes, and doesn't actually introduce any extra levels of run-time nesting to function calls, I'm not clear on why you bothered with a hybrid implementation instead of sticking with pure Python. (To clarify what I mean: using the example in the doc patch, the extra layer of run-time nesting from @decorator's wrapper function applies only to the @logged decorator, not to the function 'print_nested'. If an application has a decorated function definition in a performance critical path, a little bit of extra overhead from @decorator is the least of its worries.) Also, I thought we were trying to move away from modules that shared a name with one of their public functions or classes. As it is, I'm not even sure that a name like "decorator" gives the right emphasis. In general, decorators belong in the appropriate domain-specific module (similar to context managers). In this case, though, the domain is the manipulation of Python functions - maybe the module should be called "metafunctions" or "functools" to reflect its application domain, rather than the coincidental fact that its first member happens to be a decorator. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
Nick Coghlan wrote:
Georg Brandl wrote:
Hi,
to underlay my proposals with facts, I've written a simple decorator module containing at the moment only the "decorator" decorator.
Sorry, I forgot the initial comment which was meant to be "Thanks for moving this proposal forward" :) It's currently all too easy to write decorators that don't play nicely with introspection. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
Nick Coghlan wrote:
Georg Brandl wrote:
Hi,
to underlay my proposals with facts, I've written a simple decorator module containing at the moment only the "decorator" decorator.
It is implemented as a C extension module _decorator which contains the decorator object (modelled after the functional.partial object) and a Lib/decorator.py to allow further decorators added as Python code.
Comes with docs and unit test.
Given that @decorator is a definition time only operation to modify a function's __name__, __doc__ and __dict__ attributes, and doesn't actually introduce any extra levels of run-time nesting to function calls, I'm not clear on why you bothered with a hybrid implementation instead of sticking with pure Python.
Good question... partly because I wanted to make myself more intimate with the C API and extension modules. Everyone can write that in Python... <wink>
(To clarify what I mean: using the example in the doc patch, the extra layer of run-time nesting from @decorator's wrapper function applies only to the @logged decorator, not to the function 'print_nested'. If an application has a decorated function definition in a performance critical path, a little bit of extra overhead from @decorator is the least of its worries.)
Right. I'm not opposed to a Python-only module, I've had my fun :)
Also, I thought we were trying to move away from modules that shared a name with one of their public functions or classes. As it is, I'm not even sure that a name like "decorator" gives the right emphasis.
I thought about "decorators" too, that would make "decorators.decorator". Hm.
In general, decorators belong in the appropriate domain-specific module (similar to context managers). In this case, though, the domain is the manipulation of Python functions - maybe the module should be called "metafunctions" or "functools" to reflect its application domain, rather than the coincidental fact that its first member happens to be a decorator.
Depends on what else will end up there. If it's "memoize" or "deprecated" then the name "functools" doesn't sound too good either. Georg
Georg Brandl wrote:
Also, I thought we were trying to move away from modules that shared a name with one of their public functions or classes. As it is, I'm not even sure that a name like "decorator" gives the right emphasis.
I thought about "decorators" too, that would make "decorators.decorator". Hm.
I personally like pluralized modules for exactly the reason that they don't clash as much with members or likely local variables. datetime.datetime frequently leads me to make mistakes.
In general, decorators belong in the appropriate domain-specific module (similar to context managers). In this case, though, the domain is the manipulation of Python functions - maybe the module should be called "metafunctions" or "functools" to reflect its application domain, rather than the coincidental fact that its first member happens to be a decorator.
Depends on what else will end up there. If it's "memoize" or "deprecated" then the name "functools" doesn't sound too good either.
memoize seems to fit into functools fairly well, though deprecated not so much. functools is similarly named to itertools, another module that is kind of vague in scope (though functools is much more vague). partial would make just as much sense in functools as in functional. -- Ian Bicking | ianb@colorstudy.com | http://blog.ianbicking.org
On Mar 12, 2006, at 11:16 AM, Ian Bicking wrote: ...
memoize seems to fit into functools fairly well, though deprecated not so much. functools is similarly named to itertools, another module that is kind of vague in scope (though functools is much more vague). partial would make just as much sense in functools as in functional.
Couldn't we merge functools and functional into just one (user- visible) module? The distinction between what goes into one vs the other is exceedingly subtle and poor users will be guessing as to what's where. If we need a mixed module with something in C and something in Python, we can do it the usual way, func.py wrapping _func.pyd (or .so or whatever)... Alex
[Ian Bicking]
memoize seems to fit into functools fairly well, though deprecated not so much. functools is similarly named to itertools, another module that is kind of vague in scope (though functools is much more vague). partial would make just as much sense in functools as in functional.
[Alex]
Couldn't we merge functools and functional into just one (user- visible) module? The distinction between what goes into one vs the other is exceedingly subtle and poor users will be guessing as to what's where. If we need a mixed module with something in C and something in Python, we can do it the usual way, func.py wrapping _func.pyd (or .so or whatever)...
+1 on putting the tools all in one module. With respect to decorator entries, I would like to see python-dev collectively decide to show restraint. There are so many ways to write and use decorators that best-of-the-best are not yet obvious. Hopefully, collections of decorators will be allowed to grow-in-the-wild as recipes and as third-party modules before being put into the core. Georg's proposal seems like a good candidate for a first entry -- its chief virtue being that it may help people avoid writing crummy decorators. If his goes in, hopefully it will not fall down a slippery slope and trigger an avalance of immature decorators being added to the core. my-two-cents, Raymond
Alex Martelli wrote:
On Mar 12, 2006, at 11:16 AM, Ian Bicking wrote: ...
memoize seems to fit into functools fairly well, though deprecated not so much. functools is similarly named to itertools, another module that is kind of vague in scope (though functools is much more vague). partial would make just as much sense in functools as in functional.
Couldn't we merge functools and functional into just one (user- visible) module? The distinction between what goes into one vs the other is exceedingly subtle and poor users will be guessing as to what's where. If we need a mixed module with something in C and something in Python, we can do it the usual way, func.py wrapping _func.pyd (or .so or whatever)...
I agree it makes sense to have "decorator", "memoize", "deprecated" and "partial" all being members of the same module, whether the name be "functools" or "functional" (although I have a slight preference for "functools" due to the parallel with "itertools"). On the question of whether or not deprecated fits in as a function tool, I know I'd tend to only use it on functions (to deprecate a class, I'd simply decorate the class's __init__ or __new__ method). Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
[Nick Coghlan]
I agree it makes sense to have "decorator", "memoize", "deprecated" and "partial" all being members of the same module, whether the name be "functools" or "functional" (although I have a slight preference for "functools" due to the parallel with "itertools").
I like "functools" for a different reason -- the name is sufficiently broad so that we don't have fret about whether a particular tool fits within the module's scope. In contrast, a name like "functional" suggests that some of these tools don't quite fit. Raymond
Nick Coghlan wrote:
Alex Martelli wrote:
On Mar 12, 2006, at 11:16 AM, Ian Bicking wrote: ...
memoize seems to fit into functools fairly well, though deprecated not so much. functools is similarly named to itertools, another module that is kind of vague in scope (though functools is much more vague). partial would make just as much sense in functools as in functional.
Couldn't we merge functools and functional into just one (user- visible) module? The distinction between what goes into one vs the other is exceedingly subtle and poor users will be guessing as to what's where. If we need a mixed module with something in C and something in Python, we can do it the usual way, func.py wrapping _func.pyd (or .so or whatever)...
I agree it makes sense to have "decorator", "memoize", "deprecated" and "partial" all being members of the same module, whether the name be "functools" or "functional" (although I have a slight preference for "functools" due to the parallel with "itertools").
+1 from me. I'll happily make the according changes if that reaches a consensus.
On the question of whether or not deprecated fits in as a function tool, I know I'd tend to only use it on functions (to deprecate a class, I'd simply decorate the class's __init__ or __new__ method).
I suppose it would be okay, since as a decorator it can only be applied to functions. In PEP 356, there is even a suggestion to "add builtin @deprecated decorator?". Cheers, Georg
On 3/12/06, Raymond Hettinger
[Nick Coghlan]
I agree it makes sense to have "decorator", "memoize", "deprecated" and "partial" all being members of the same module, whether the name be "functools" or "functional" (although I have a slight preference for "functools" due to the parallel with "itertools").
I like "functools" for a different reason -- the name is sufficiently broad so that we don't have fret about whether a particular tool fits within the module's scope. In contrast, a name like "functional" suggests that some of these tools don't quite fit.
FWIW, +1 here. Especially if we're only going to add two functions -- ``partial``, which is already accepted, and Georg's ``decorator`` -- it seems like overkill to introduce a module for each. I agree that "functools" is a better module name if both ``partial`` and ``decorator`` are going in there. STeVe -- Grammar am for people who can't think for myself. --- Bucky Katt, Get Fuzzy
Raymond Hettinger wrote:
In PEP 356, there is even a suggestion to "add builtin @deprecated decorator?".
Restraint please.
Well, that sentence wasn't meant in the sense of "we should add it" but in the sense of "why shouldn't we put it in functools _if_ we add it, when it's even suggested as a builtin" ;) Georg
participants (6)
-
Alex Martelli
-
Georg Brandl
-
Ian Bicking
-
Nick Coghlan
-
Raymond Hettinger
-
Steven Bethard