473,387 Members | 1,391 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Problem with reimporting modules

I'm currently investigating a problem that can hit you in TurboGears
when Kid template modules are reloaded in the background, because in
certain situations, global variables suddenly are set to None values.

I tracked it down to the following behavior of Python. Assume you have a
module hello.py like that:

---- hello. py ----
greeting = 'Hello!'
def print_hello():
print greeting
-------------------

Now run the following code:

from hello import print_hello
print_hello()
import sys
del sys.modules['hello'] # delete module
import hello # recreate module
print_hello()

The second print_hello() prints "None" instead of "Hello!". Why is that?
I had expected that it either prints an error or print "Hello!" as well.

Is this intended behavior of Python?

-- Christoph
Feb 11 '07 #1
4 1247
On Feb 11, 5:53 am, Christoph Zwerschke <c...@online.dewrote:
I'm currently investigating a problem that can hit you in TurboGears
when Kid template modules are reloaded in the background, because in
certain situations, global variables suddenly are set to None values.

I tracked it down to the following behavior of Python. Assume you have a
module hello.py like that:

---- hello. py ----
greeting = 'Hello!'
def print_hello():
print greeting
-------------------

Now run the following code:

from hello import print_hello
print_hello()
import sys
del sys.modules['hello'] # delete module
import hello # recreate module
print_hello()

The second print_hello() prints "None" instead of "Hello!". Why is that?
I had expected that it either prints an error or print "Hello!" as well.

Is this intended behavior of Python?

-- Christoph
You're most likely looking for reload:
http://docs.python.org/lib/built-in-funcs.html#l2h-61
The documentation does imply that deleting a module from sys.modules
may not be what you want:
http://docs.python.org/lib/module-sys.html#l2h-5147
>>import sys
import warnings as previous_warnings # for example
# testing whether reload returns the same module object:
.... reload(previous_warnings) is previous_warnings
True
>># the following result is rather intuitive, but for
.... # the sake of demonstration, I'll do it anyway.
.... del sys.modules['warnings']
>>import warnings as after_warnings
after_warnings is previous_warnings
False

Feb 11 '07 #2
Yes I know about reload(), but TurboGears (TurboKid) does not use it and
the docs say that removing modules from sys.module is possible to force
reloading of modules. I don't want to rewrite everything since it's a
pretty complex thing with modules which are compiled from templates
which can depend from other templates etc...
Feb 11 '07 #3
En Sun, 11 Feb 2007 15:56:16 -0300, Christoph Zwerschke <ci**@online.de>
escribió:
Yes I know about reload(), but TurboGears (TurboKid) does not use it and
the docs say that removing modules from sys.module is possible to force
reloading of modules. I don't want to rewrite everything since it's a
pretty complex thing with modules which are compiled from templates
which can depend from other templates etc...
If you remove the module from sys.modules, when you import it again you
end up with a *new*, fresh, module object, unrelated to the original one.

Quoting your original message again:
I tracked it down to the following behavior of Python. Assume you have a
module hello.py like that:
---- hello. py ----
greeting = 'Hello!'
def print_hello():
print greeting
-------------------
Now run the following code:
from hello import print_hello
print_hello()
import sys
del sys.modules['hello'] # delete module
import hello # recreate module
print_hello()
The second print_hello() prints "None" instead of "Hello!". Why is that?
Notice that you are mixing references here. You first import print_hello
from hello, and after deleting the module, you import hello (not
print_hello). And you expect that your old reference to print_hello now
refers to the new function. The whole point of reloading/reimporting a
module is to get the *new* contents, but that only works if you refer to
things using the module.function notation, not if you hold a reference to
the function (which will always be the original function).

In short, your code should be:

import hello
hello.print_hello()
import sys
del sys.modules['hello']
import hello
hello.print_hello()

or, using reload:

import hello
hello.print_hello()
reload(hello)
hello.print_hello()

If you think that always typing module.function is too much - well, don't
try to reload modules then :)
Somewhere I read that at Google the policy is to always import modules,
never functions, and this may be a good reason for it.

If you want to know the details: print_hello doesn't hold a reference to
the containing module, only to its namespace, in the func_globals
attribute. When you delete the last reference to the module, it gets
destroyed. At that time, all values in the module namespace are set to
None (for breaking possible cycles, I presume). print_hello now has a
func_globals with all names set to None. (Perhaps the names could have
been deleted instead, so print_hello() would raise a NameError, but I'm
just describing the current CPython implementation)

--
Gabriel Genellina

Feb 11 '07 #4
Thanks for the detailed explanations, Gabriel.
At that time, all values in the module namespace are set to
None (for breaking possible cycles, I presume). print_hello now has a
func_globals with all names set to None. (Perhaps the names could have
been deleted instead, so print_hello() would raise a NameError, but I'm
just describing the current CPython implementation)
Yes, that was the thing that confused me a bit. I had expected that an
error is raised or that the namespace has a reference to the module and
is reestablished when the module has been reloaded.

Anyway, I have solved the problem in a different way now.

-- Christoph
Feb 11 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Remy Cool | last post by:
Hello, I've created an archive import class (with the help of importers.py from the python /demo/imputil dir) which imports packages and modules from a dictionary. So far so good. The problem...
0
by: alejandro david weil | last post by:
Hello! I got the next problem and didn't see any reference to the behaviour that produces it, look: If we have a module like: --- mod.py --------------->8------ testvar2 = 15
4
by: gnah | last post by:
Greetings, I hope my problem is easy to fix, I'm pretty new with php - but I am getting weird results with the opendir() function. It may just be a path problem, but I don't see which variable...
11
by: Sambo | last post by:
I have the following module: ------------------------------- import math def ac_add_a_ph( amp1, ph1, amp2, ph2 ): amp3 = 0.0 ph3 = 0.0 ac1 = ( 0, 0j ) ac2 = ( 0, 0j )
0
by: zhenya.tkachenko | last post by:
Hi! Have a problem with mod_auth_mysql. Compilation and installation of module done ok: # /usr/local/apache/bin/apxs -c -L/usr/lib/mysql -I/usr/include/mysql -lmysqlclient -lm -lz...
6
by: superdevo | last post by:
Hey everyone, I seem to be having a problem with my CSS in IE 7. The problem does not show up in FireFox though. I've setup an online store that originally had a #wrapper "container" and #body...
1
by: spatro | last post by:
Hi, I am trying to install DBD::mysql using the CPAN and I am facing the following error: cpan> install DBD::mysql CPAN: Storable loaded ok Going to read /root/.cpan/Metadata Warning:...
3
by: Mohamed Yousef | last post by:
Hello , The problem I'm asking about is how can imported modules be aware of other imported modules so they don't have to re-import them (avoiding importing problems and Consicing code and...
0
by: Rafe | last post by:
Hi, This seems to be an old question, and I've read back a bit, but rather than assume the answer is "you can't do that", I'd thought I'd post my version of the question along with a...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.