[Python-Dev] [Python-checkins] peps: Add PEP 422: Dynamic Class Decorators
Tres Seaver
tseaver at palladion.com
Wed Jun 6 02:53:44 CEST 2012
On 06/05/2012 07:38 PM, Nick Coghlan wrote:
> On Wed, Jun 6, 2012 at 9:06 AM, PJ Eby <pje at telecommunity.com> wrote:
>>
>>
>> On Tue, Jun 5, 2012 at 5:31 PM, Terry Reedy <tjreedy at udel.edu>
>> wrote:
>>>
>>> On 6/5/2012 2:26 PM, PJ Eby wrote:
>>>> It's for symmetry and straightforward translation with stacked
>>>> decorators, i.e. between:
>>>>
>>>> @deco1 @deco2 [declaration]
>>>>
>>>> and __decorators__ = [deco1, deco2]
>>>>
>>>> Doing it the other way now means a different order for people
>>>> to remember; there should be One Obvious Order for decorators,
>>>> and the one we have now is it.
>>>
>>>
>>> You and I have different ideas of 'obvious' in this context.
>>
>>
>> To be clearer: I've written other APIs which take multiple
>> decorators, or things like decorators that just happen to be a
>> pipeline of functions to be applied, and every time the question of
>> what order to put the API in, I always put them in this order
>> because then in order to remember what the order was, I just have to
>> think of decorators. This is easier than trying to remember which
>> APIs use decorator order, and which ones use reverse decorator
>> order.
>>
>> So, even though in itself there is no good reason for one order over
>> the other, consistency wins because less thinking. At the least, if
>> they're not going to be in decorator order, the member shouldn't be
>> called "__decorators__". ;-)
>
> Yeah, I can actually make decent arguments in favour of either order,
> but it was specifically "same order as lexical decorators" that
> tipped the balance in favour of the approach I wrote up in the PEP.
>
> It's also more consistent given how the base classes are walked.
> While I'm not proposing to calculate it this way, you can look at the
> scheme the PEP as:
>
> # Walk the MRO to build a complete decorator list decorators = [] for
> entry in cls.mro():
> decorators.extend(cls.__dict__.get("__decorators__", ()) # Apply the
> decorators in "Last In, First Out" order, just like unwinding a chain
> of super() calls for deco in reversed(decorators): cls = deco(cls)
Or, to make it obvious we are treating 'decorators' as a stack::
while decorators:
cls = decorators.pop()(cls)
--
===================================================================
Tres Seaver +1 540-429-0999 tseaver at palladion.com
Palladion Software "Excellence by Design" http://palladion.com
More information about the Python-Dev
mailing list