[python-uk] Advice on decorator grammar

Simon Yarde simonyarde at me.com
Wed Apr 3 19:42:02 CEST 2013


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 <simonyarde at 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 at python.org
> http://mail.python.org/mailman/listinfo/python-uk
> 
> _______________________________________________
> python-uk mailing list
> python-uk at python.org
> http://mail.python.org/mailman/listinfo/python-uk

Simon Yarde

07525 063 134
simonyarde at me.com



More information about the python-uk mailing list