On Monday 2004-04-05 at 15:42, Andrew Koenig wrote: > Here's what I don't understand. > > I imagine that most of the time, when someone decorates a function with lots > of attributes, there is at least the possibility of decorating more than one > function with the same set of attributes. > > In such a case, doesn't it make sense to bind a variable to the attributes > and use it instead? > > Attributes = [staticmethod, classmethod, > otherattributes(debug=True)] > > def foo(bar, baz) Attributes: > pass > > And doesn't this idea answer the objection that too many attributes after > the parameter list make the definition hard to read? It certainly answers that objection, but it has (so it seems to me) other problems of its own; see below. > For that matter, why do we need the brackets if there is only one attribute: > > def foo(bar, baz) staticmethod: > pass > > I am suggesting that what comes between the ) and the : should be an > expression, which must evaluate to either a callable or a sequence of > callables. For that matter, why not allow a tuple expression without > parentheses: > > def foo(bar, baz) staticmethod, classmethod: > pass > > Whatever sequence you put there, I think the semantics are clear: Before > binding a name to the function, pass it to the callable or in turn to each > element of the sequence. The brackets serve multiple purposes. - They make the decoration *look*, even to novice eyes, like an annotation: "by the way, please make this a static method". - They may possibly help the parser a little. (I'm showing my ignorance here; I haven't really looked at the Python parser at all.) - They give a hint to the user that what goes in between them may be a sequence, not just a single item. - They ensure that all decorated definitions have a somewhat consistent appearance. Omitting them breaks all these things, especially if an arbitrary expression is allowed there. And do we really want to allow def foo(bar, baz) quux(wibble, spong): pass That's not a hideous pathological case; it's what a simple decoration using a parameterized decorator will look like without the brackets. With good decorator names I suppose it becomes somewhat comprehensible: def foo(bar, baz) memoized(25): pass but surely it's still much clearer when written as def foo(bar, baz) [memoized(25)]: pass or even (though I'm a little tempted to agree with whoever it was that was wondering whether Guido has been abducted by aliens) [memoized(25)] def foo(bar, baz): pass We can keep the syntactic distinctiveness while still allowing multiple decorators to be combined, by having a function (a builtin, perhaps, but it's not hard to write) that composes decorators: def compose(*decorators): def _(f): for d in decorators: f = d(f) return f our_attributes = compose(staticmethod, classmethod, otherattributes(debug=True)) def foo(bar, baz) [our_attributes]: pass -- Gareth McCaughan
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4