Thanks Nick. I wonder if you see any use or validity in an expanded grammar allowing class-initialisation within the decorator syntax?
Or as Stestagg suggests, there is no real practical need for it? > decoratedfoo.orig(1, 2) # run original function Thanks for highlighting decorator-pattern-like-access, with the inner object available from the outer, and perhaps exposing methods beyond __call__ too, i.e. ``decorated.orig.some_method()``. > @mydecorator > def foo(a, b): > pass > > is identical to > > def foo(a, b): > pass > foo = mydecorator(foo) I hoped to pick this one up with the example below.. it is presently a workaround to apply an instance-method decorator due to syntax restrictions. def f(): pass f = A('foo').some_process(f) == @A('foo').some_process # raises syntax error def f(): pass On 4 Apr 2013, at 10:16, Nick Murdoch wrote: > Hi Simon, > > It might be of use to you to know that the decorator syntax is actually a > syntactic shortcut for a longer way of writing the same thing. > > For instance, > > @mydecorator > def foo(a, b): > pass > > is identical to > > def foo(a, b): > pass > foo = mydecorator(foo) > > > If you wanted to only apply the decorator at certain times, you could call > the decorator directly when you need it. There'd be a bit of overhead since > you're re-running the decorator function each time, but I'll leave it to you > to decide whether that's a problem for your use case. > > For example: > > foo(1, 2) # runs without decoration > mydecorator(foo)(1, 2) # runs with decoration > > You could expand this further, for instance your decorator could expose the > original function so you don't have to keep on re-running the decorator. > > decoratedfoo = mydecorator(foo) # create decorated function > decoratedfoo(1, 2) # run decorated function > decoratedfoo.orig(1, 2) # run original function > > Hope that helps, > > Nick > > On Wed, Apr 03, 2013 at 06:42:02PM +0100, Simon Yarde wrote: >> This may well be moot, so thank you for chipping in. All your suggestions >> are completely valid and practical. >> >> And thank you Stestagg and a.cavallo for commenting on references; I've >> tried to show in the examples below how the instance might be used to store >> config that is accessed by instance-methods, so external access was not an >> issue for the scenario I was envisaging. >> >> I'm interested in decorator-methods that can be employed in different >> scenarios; as 'python decorators'; and using a decorator-pattern for dynamic >> decoration of callables. >> >> The grammar seems to preclude such flexibility, and a certain elegance. >> >> I'll try to set-out a possible flexible design-pattern that shows the same >> decorator-method employed flexibly, and where it becomes inelegant or >> unintuitive. >> >> This works: >> >> def f(): >> pass >> >> f = A('foo').some_process(f) >> >> This 'could' work, where it not for grammar inconsistency: >> >> @A('foo').some_process >> def f(): >> pass >> >> The same pattern enables dynamic decoration using different instances of A: >> >> @apply_some_process_from_one_of_these_at_random( >> A('foo'), >> A('bar') >> ) >> def f(): >> pass >> >>> You could do this by making decorator_method a classmethod: >>> >>> @MyDecorator.decorate_this(foo) >> >> >> Using a class-method, I would have to name the method I wanted to call and >> supply initialisation at the same time, and return a configured callable to >> perform the desired process: >> >> @apply_some_process_from_one_of_these_at_random( >> A.some_process('foo') >> A.some_process('bar') >> ) >> >> It's attractive not to have to name the process to be called at >> configuration, and to be able to store configuration in the instance (this >> works): >> >> @apply_an_arbitrary_process_from( >> A('foo') >> ) >> >> and it would be elegant/consistent to be able to apply a process using the >> decorator-syntax if need be (this doesn't work because of the grammar): >> >> @A('foo').some_other_process >> >> >> On 3 Apr 2013, at 12:43, Stestagg wrote: >> >>> This seems redundant to me, the MyDecorator instance would not be bound to >>> anything, so you'll 'loose' the reference to it, except through the call to >>> decorator_method(). >>> >>> You could do this by making decorator_method a classmethod: >>> >>> class MyDecorator(object): >>> >>> @classmethod >>> def decorate_this(cls, ...): >>> pass >>> >>> allowing you to use it: >>> >>> @MyDecorator.decorate_this(foo) >>> >>> If your intent is to pass arguments to the MyDecorator instance, just pass >>> them to the decorator method directly. >>> >>> Finally, if you're trying to implement singleton like behaviour. (a >>> registry etc..) then using your example of binding an instance of >>> MyDecorator() to a module-level name is sensible. >>> >>> MY_REGISTRY = MyDecorator() >>> >>> @MY_REGISTRY.decoate_this() >>> def wrapped(): >>> ... >>> >>> Does your use-case match any of these? >>> >>> Thanks >>> >>> Steve >>> >>> >>> On Wed, Apr 3, 2013 at 12:34 PM, Simon Yarde <simonya...@me.com> wrote: >>> Hi All >>> >>> I've not posted to this list before. Hello! >>> >>> I have a question about decorators and have failed to devise a search that >>> has thrown up any history of discussion on this particular matter. >>> >>> Does the following seem like something that 'should' work? Or is anyone >>> aware of a source of documentation that explains historically why the >>> following syntax might not be allowed? >>> >>> I hope this sort of conundrum/discussion-point is appropriate to this >>> forum; I'm not on python-dev and this is obviously not a bug. >>> >>> So.. >>> >>> Decorator grammar is this: >>> >>> decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE >>> >>> The grammar prevents this: >>> >>>>>> class MyDecorator: >>> ... def decorator_method(): >>> ... pass >>> ... >>>>>> @MyDecorator().decorator_method() >>> File "<stdin>", line 1 >>> @MyDecorator().decorator_method() >>> ^ >>> SyntaxError: invalid syntax >>> >>> But is possible to achieve the desired effect by assigning the class >>> instance to variable: >>> >>>>>> mydecorator = MyDecorator() >>> ... @mydecorator.decorator_method >>> ... def f(): >>> >>> >>> My initial thoughts were that the syntax provided a neat way to provide a >>> configurable decorator class instance with a number of alternative >>> decorator-function generating methods, rather than just the usual __call__. >>> >>> S >>> _______________________________________________ >>> python-uk mailing list >>> python-uk@python.org >>> http://mail.python.org/mailman/listinfo/python-uk >>> >>> _______________________________________________ >>> python-uk mailing list >>> python-uk@python.org >>> http://mail.python.org/mailman/listinfo/python-uk >> >> Simon Yarde >> >> 07525 063 134 >> simonya...@me.com >> >> _______________________________________________ >> python-uk mailing list >> python-uk@python.org >> http://mail.python.org/mailman/listinfo/python-uk > _______________________________________________ > python-uk mailing list > python-uk@python.org > http://mail.python.org/mailman/listinfo/python-uk _______________________________________________ python-uk mailing list python-uk@python.org http://mail.python.org/mailman/listinfo/python-uk