atexit.register does not return the registered function. IMHO, it should.
prouleau001 at gmail.com
prouleau001 at gmail.com
Thu Nov 16 11:03:48 EST 2006
Hi all!
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::
>>> import atexit
>>> @atexit.register
... def goodbye():
... print "Goodbye, terminating..."
...
>>> goodbye()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'NoneType' object is not callable
>>>
>>> goodbye
>>> type(goodbye)
<type 'NoneType'>
>>>
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::
>>> def atexit_register(fct):
... atexit.register(fct)
... return fct
...
>>> @atexit_register
... def goodbye2():
... print "Goodbye 2!!"
...
>>> goodbye2()
Goodbye 2!!
>>> goodbye2
<function goodbye2 at 0x009DD930>
>>>
.. References
.. _atexit.register():
http://www.python.org/doc/current/lib/module-atexit.html
.. _Python 2.4 Decorators\: Reducing code duplication and consolidating
knowledge: http://www.ddj.com/184406073
More information about the Python-list
mailing list