Mailing List Archive

Module magic methods
Do modules have magic methods? Specifically, I'm wondering if there's a
__del__() or __destroy__() method that I could use to clean up after myself
a little when the module is about to be unloaded...

--
----------================================================---------- _
Chris Herborth, R&D, Technical Writing | \ _
Arcane Dragon Software Arcane Dragon -==(UDIC)==- | < /_\
arcane dragon at home dot com DNRC Holder of Past Knowledge |_/ \_
Module magic methods [ In reply to ]
arcanedragonNOSPAM@NOSPAMhome.com (Chris Herborth) writes:

> Do modules have magic methods? Specifically, I'm wondering if there's a
> __del__() or __destroy__() method that I could use to clean up after myself
> a little when the module is about to be unloaded...

Don't think so. However you can fake it by creating a class instance
and storing it in a module global, like so:

class ByeBye:
def __del__(self):
print "bye bye"

_byebye = ByeBye()

Then, so long as no other entity has a reference to _byebye, when the
module is unloaded _byebye will be collected and the __del__ method
called.

You know that, in general, modules aren't unloaded, except at
interpreter shutdown time? And then the execution state is so
unpredictable you can't really do anything?

HTH
Michael

FWIW, I've often thought it would be funky to be able to define
__add__ or __call__ etc methods to modules. Pointless, I'd have to
admit, but still funky.

> --
> ----------================================================---------- _
> Chris Herborth, R&D, Technical Writing | \ _
> Arcane Dragon Software Arcane Dragon -==(UDIC)==- | < /_\
> arcane dragon at home dot com DNRC Holder of Past Knowledge |_/ \_
Module magic methods [ In reply to ]
Michael Hudson (mwh21@cam.ac.uk) wrote:
>
> You know that, in general, modules aren't unloaded, except at
> interpreter shutdown time? And then the execution state is so
> unpredictable you can't really do anything?
>
> HTH
> Michael
>

Witticisms by Dave: "Questions on comp.lang.python are like clothes
hangers in your closet. You try to pull out one, and twenty come
tangled to it."

Maybe, in general, modules aren't unloaded. But what if I do:

import mymodule
#
# Do some stuff with mymodule
#
mymodule = None

Won't reference counting cause the space taken up by mymodule to be
garbage collected? I hope so, because, where I work, this is what
I'm going to tell them to do when they want to reclaim space in
long running programs.

[Pause for thought and experimentation with Python ... ]

Oops. Wait a minute. What if I create an instance on of class
defined in mymodule:

anInstance = mymodule.MyClass()
mymodule = None
anInstance.show()

Something must stay around so that I can call the methods defined
MyClass.

[Pause for more heavy thinking in a light-weight brain ...]

OK, then what about after all the reference counts for instances of
mymodule go to zero?

anInstance = None

- Dave
Module magic methods [ In reply to ]
In article <m3g13wt71h.fsf@atrus.jesus.cam.ac.uk>,
Michael Hudson <mwh21@cam.ac.uk> wrote:
>
>FWIW, I've often thought it would be funky to be able to define
>__add__ or __call__ etc methods to modules. Pointless, I'd have to
>admit, but still funky.

Not so pointless, imo, because a module is just a singleton class
with a light dusting of nonstandard syntax and semantics. I've
been bitten now and again by the differences (don't ask), and I
compiled a list of the differences. Some are superficial, and some
are significant:

o Classes are defined by the block a "class" statement contains; a
module is defined by the contents of its file (sort of).

o Instances of classes are created by the __init__ method of the
class (mostly), and a module instance is created with the "import"
statement.

o Type-checking is performed on a call to a method of a class to
guarantee that the first argument is the same class as the class the
method belongs to (sigh), whereas no such type checking is performed
on functions inside a module.

o Assigning to a instance attribute of the same name as a class
variable will just shadow the class attribute for that instance.
For the module, no such shadowing happens. That is,

>>> class Foo:
q = 'foo'

>>> x = Foo()
>>> x.q = 'bar'
>>> print x.q
bar
>>> print Foo.q
foo

>>> import math
>>> print math.pi
3.14159265359
>>> math.pi = 3
>>> print math.pi
3
>>> del math; import math
>>> print math.pi
3

Right now, since classes and modules are built-in types, so we don't
have access to what makes them different. So you can't have a module
intializer that you can pass information to, for example. But in the
promised land of Python 2.0, when types and classes are unified, it
may be possible to do things like this:

class WhyWhyWhy(Module, Class):
[...]

In addition to just being gross, notice how we've snuck a metaclass
into the equation. This would just be too cool, wouldn't it? :)


Neel
Module magic methods [ In reply to ]
"G. David Kuhlman" wrote:
>
> import mymodule
> #
> # Do some stuff with mymodule
> #
> mymodule = None
>
> Won't reference counting cause the space taken up by mymodule to be
> garbage collected?

Nope, because references all imported modules are kept
on a global list in the bowels of the interpreter, so
that the next time the module is imported you get a
reference to the previously loaded instance.

> this is what
> I'm going to tell them to do when they want to reclaim space in
> long running programs.

It won't work.

> anInstance = mymodule.MyClass()
> mymodule = None
> anInstance.show()
>
> Something must stay around so that I can call the methods defined
> MyClass.

The instance has a reference to the class, so as long as the
instance is alive the class will be too, even if you wipe
out the reference to it in the module where it was defined.

Greg