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

Reply via email to