i figured that the best pythonic way would be to put a decorator on an
entire module, if the entire module was to be compiled to javascript.
... however, i don't know how to do that!
@decorate(module) ?
@decorator()
import modulename
?
should this work?
many thanks,
l.
Function-by-function or class-by-class. There is no decorator support for
modules.
--
Skip Montanaro - sk...@pobox.com - http://smontanaro.dyndns.org/
awWww! i'm going to quietly throw my toys out of my pram.
... but seriously - doesn't that strike people as... a slightly odd
omission?
l.
Not really; functions and classes are explicitly defined by "def .."
and "class ...", modules are not.
You can always pass the module to the decorator explicitly:
import mymod
mymod = decorator(mymod)
George
lkcl> ... but seriously - doesn't that strike people as... a slightly
lkcl> odd omission?
Decorators are still a new feature in the language and were purposely added
in an incremental fashion. In 2.5 they were added for functions. Suitable
use cases were found to apply them to classes in 2.6. You could post your
needs to the python...@python.org list and see if they gain any traction
there. If so, perhaps decorators for modules can be added for 2.7.
One obvious question about module decorators would be where to apply them.
In your original post you suggested perhaps applying it at import time:
@compiletojs
import mypyjamasmodule
What if somewhere else in your application you had a naked import:
import mypyjamasmodule
Should that be compiled into normal Python bytecode?
I suspect in most instances you'd want a module compiled one way or the
other. To avoid errors you probably want the decorator inside the module
(somewhere - at the top?). Unfortunately, there is no keyword upon which
you can hang a decorator as you can with functions (def) and classes
(class). import is not the same as a definition.
It's not obvious to me that module decorators would use precisely the same
sort of syntax as function and class decorators.
Skip
You can do something like this:
def decorate_functions(decorator, module):
Function = type(lambda:0), type(len)
for name, obj in module.__dict__.iteritems():
if isinstance(obj, Function):
setattr(module, name, decorator(obj))
Example:
>>> def trace(f):
... def decorated(*args, **kwargs):
... print 'calling', f.__name__
... return f(*args, **kwargs)
... return decorated
...
>>> import math
>>> decorate_functions(trace, math)
>>> math.log(math.tan(math.pi/4))
calling tan
calling log
-1.1102230246251565e-16
--
Arnaud
Decorators are applied when the function or class is *defined*. Modules
OTOH are imported from quite a few places. So what would
@foo
import bar
@baz
import bar
mean - what's the semantics of that? If *anything*, you could declare a
decorator per module.
Anyway, for your original problem, you can always just iterate over the
module objects & decorate them. Like this:
for name in dir(module):
thing = getattr(module, name)
if callable(thing):
wrapped_thing = wrap(thing)
setattr(module, name, wrappend_thing)
Diez
@decorator
def/class possibly_long_name ...
abbreviates
def/class possibly_long_name ...
<possibly many lines running off screen or page>
possibly_long_name = decorator(possibly_long_name)
thereby warning the reader at the beginning that possibly_long_name will
be rebound and avoiding typing possibly_long_name thrice.
Neither consideration applies to module imports.
Wrapping the functions and classed inside the module does not wrap the
module, it mutates it. Module names tend to be short and would only
need to be written twice, not thrice. And the mutation call would
immediately follow the import line, so readers can easily see what happens.
No.
Strictly speaking, to talk about applying a decorator to a module means
syntactic sugar for the following:
import mymodule
mymodule = decorator(mymodule)
Since it's only two lines, it's not a great hardship to expect people to
call the decorator directly, instead of having syntactic sugar for it.
The only hard part is to write the function decorator() itself -- and it
isn't clear what that should possibly do. Function and class decorators
wrap functions and classes, so presumably module decorators should wrap
the module object itself.
But that doesn't seem to be what you want: you want it to look inside the
module and wrap the individual functions and classes inside it. All of
them? Wrap them with what? What about other objects? Should it wrap
callable class instances ("functors") as well as the classes themselves?
Metaclasses? Functions imported from other modules?
There's too many possible answers to these questions to expect this to be
standard part of Python. In other words, this is an application-level
task, not a language task, which means it's your job, not the standard
library's.
--
Steven