Since that the decorator syntax is upon us, I think it would be good if
atexit.register() was returning the function passed as argument. This
simple change to the library would solve a problem with the use of
atexit.register as a decorator (and I can't think of any use case where
this change would break any code).
I describe the problem in the following text.
Problem using atexit.register as a decorator
============================================
In his April 2005 article titled `Python 2.4 Decorators: Reducing code
duplication and consolidating knowledge`_ , Phillip Eby describes how
you can use `atexit.register()`_ from the standard Python library. He
shows how to use the decorator syntax to register a function that will
execute at program termination. Here is how it goes::
@atexit.register
def goodbye():
print "Goodbye, terminating..."
However, there is one fundamental problem with this: atexit.register()
returns None. Since the above code corresponds to::
def goodbye():
print "Goodbye, terminating..."
goodbye = atexit.register(goodbye)
the code registers goodbye but right after it binds goodbye to None!
You can see this in the following session::
... def goodbye():>>import atexit
@atexit.register
... print "Goodbye, terminating..."
...
Traceback (most recent call last):>>goodbye()
File "<stdin>", line 1, in ?
TypeError: 'NoneType' object is not callable
<type 'NoneType'>>>>
goodbye
type(goodbye)
There is two solutions to this problem:>>>
1. Use another function to register and decorate.
2. Change atexit.register() in the Python library so that
it returns the function it registers.
Solution 1 can be implemented right away::
def atexit_register(fct):
atexit.register(fct)
return fct
@atexit_register
def goodbye2():
print "Goodbye 2!!"
and it works: it registers the function for execution at termination
but leaves goodbye2 callable::
... atexit.register(fct)>>def atexit_register(fct):
... return fct
...
... def goodbye2():>>@atexit_register
... print "Goodbye 2!!"
...
Goodbye 2!!>>goodbye2()
<function goodbye2 at 0x009DD930>>>goodbye2
... References>>>
... _atexit.register():
http://www.python.org/doc/current/li...le-atexit.html
... _Python 2.4 Decorators\: Reducing code duplication and consolidating
knowledge: http://www.ddj.com/184406073