On 4/19/05, Alex Martelli email@example.com wrote:
Well, one obvious use might be, say:
@withfile('foo.bar', 'r'): content = thefile.read()
but that would require the decorator and block to be able to interact in some way, so that inside the block 'thefile' is defined suitably.
it be better to make a function of the block wrapped in a block-decorator and then use a normal decorator?
From a viewpoint of namespaces, I think it would be better to have the block execute in the same namespace as the code surrounding it, not a separate one (assigning to 'content' would not work otherwise), so a nested function would not be all that useful. The problem might be, how does the _decorator_ affect that namespace. Perhaps:
def withfile(filename, mode='r'): openfile = open(filename, mode) try: block(thefile=openfile) finally: openfile.close()
i.e., let the block take keyword arguments to tweak its namespace (but assignments within the block should still affect its _surrounding_ namespace, it seems to me...).
I'm not a big fan of this means of tweaking the block's namespace. It means that if you use a "block decorator", you might find that names have been 'magically' added to your namespace. This has a bad code smell of too much implicitness to me...
I believe this was one of the reasons Brian Sabbey's proposal looked something like:
do <unpack_list> in <returnval> = <callable>(<params>): <code>
This way you could write the block above as something like:
def withfile(filename, mode='r'): def _(block): openfile = open(filename, mode) try: block(openfile) finally: openfile.close() return _
do thefile in withfile('foo.bar', 'r'): content = thefile.read()
where 'thefile' is explicitly named in the do/in-statement's unpack list. Personally, I found the 'do' and 'in' keywords very confusing, but I do like the fact that the parameters passed to the thunk/block are expanded in an explicit unpack list. Using @, I don't see an easy way to insert such an unpack list...
Of course, even with the unpack list, you still have to know what kind of arguments the function calls your block with. And because these only appear within the code, e.g. block(openfile) you can't rely on easily accessible things like the function's signature. It means that unlike other callables that can basically document parameters and return type, "block decorators" would have to document parameters, return type, and the parameters with which they call the block...