0

There are two Python scripts: master.py and to_be_imported.py

Here is the master.py:

import os
os.foo = 12345
import to_be_imported

And here is the to_be_imported.py:

import os    
if hasattr(os, 'foo'):
    print 'os hasattr foo: %s'%os.foo

Now when I run master.py I get this:

os hasattr foo: 12345

indicating that the imported module to_be_imported.py picks up the variable declared inside the process that imported it (master.py).

While it works fine I would like to know why it works and also to make sure it is a safe practice.

5
  • 1
    os.foo = 12345 - messing with other modules' attributes like that is a really bad idea. Commented Mar 31, 2016 at 18:42
  • Please clarify using real facts why it would be a bad idea. Commented Mar 31, 2016 at 18:49
  • Is there other "better" way of doing it? Commented Mar 31, 2016 at 18:50
  • the module might have a variable of the same name which it might be heavily dependent on. If you change it then you may fall into unexpected behavior Commented Mar 31, 2016 at 18:51
  • Makes sense. Thanks! Commented Mar 31, 2016 at 19:35

2 Answers 2

3

If a module is already imported, subsequent imports to the module uses the cached version of the module. Even if you reference it via different names as in the following case

import os as a

import os as b

Both refer to the same os module that was imported the first time. So it is obvious that the variable assigned to a module will be shared.

You can verify it using the built-in python function id()

Sign up to request clarification or add additional context in comments.

3 Comments

Is there a way to force an import from disk and not the cached import?
Ive never found a use case to have two different copies of the same module. But do a little research on the reload function which claims to refresh the module from the disk if I am not wrong
I could imagine wanting to do it if you were experimenting with a modified version of a module. But yeah, most of the time, probably not.
2

Nothing is a bad idea per se, but you must remember few things:

  1. Modules are objects in Python. They are loaded only once and added to sys.modules. These objects can also be added attributes like regular objects (with no messy implementation of setattr).
  2. Since they are objects, but not instantiable ones, you must consider them as singletons (they are singletons, after all), and you must consider the disadvantages and benefits of such model:

    a. Singletons are only one object. Are you sure that accessing their attributes is concurrency-safe?
    b. Modules are global objects. Are you sure you can track the whole behavior and access to their members? Are you sure you will be able to debug errors there?

  3. Is the code something you will work with others?

While no idea is better than other, good practices tell us that using global variables is not well-seen, specially if we have a team to work with. On the other hand: if your code is concurrent and/or reentrant, avoid using global variables or relying on module attributes. OTOH you will have no problem assigning attributes like that. They will last for the life of your script execution.

This is not the place to chose the best alternative. Depending on how you state your problem, you can ask it either on programmers or codereview. You can chose many variants to share state without using global variables in modules, like passing those variables inside a state back and forth across arguments, or learning and using OOP. But, again, this site is no scope for that.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.