On Wed, 06 Jun 2012 09:38:39 +1000, Nick Coghlan <ncogh...@gmail.com> wrote: > On Wed, Jun 6, 2012 at 9:06 AM, PJ Eby <p...@telecommunity.com> wrote: > > > > > > On Tue, Jun 5, 2012 at 5:31 PM, Terry Reedy <tjre...@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.
I don't think about data structures lexically, though, I think of them programmatically. So I'm with Terry here, I would expect them to be in the list in the order they are going to get applied. I can see the other argument, though, and presumably other people's brains work differently and they'd be more confused by non-lexical ordering. > 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) Assuming I got this right (no guarantees :), the following is actually easier for me to understand (I had to think to understand what "just like unwinding a chain of super() calls" meant): # Walk the MRO from the root, applying the decorators. for entry in reversed(cls.mro()): for deco in cls.__dict__.get("__decorators__", ()): cls = deco(cls) --David
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com