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