質問

To make it shorter, I have a module that does this:

MyModule
----mymodule.py
----__init__.py

mymodule.py

# Get the name of the current module
current_module = __import__(__name__)
setattr(current_module, 'VarA', 5)

So if Im in located inside the MyModule folder and open a shell, the following works:

import mymodule
print mymodule.VarA

But if Im localted outside MyModule folder and do:

from MyModule import mymodule
print mymodule.VarA

I get: 'module' object has no attribute 'VarA', which I suppose is happening because setattr is setting VarA somewhere else, what is it to be done so VarA is available in mymodule no matter where I import the module from ?

役に立ちましたか?

解決

If you read the documentation for __import__:

When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned.

And you can see this very easily.

MyModule/mymodule.py:

current_module = __import__(__name__)
print current_module

Your program will print out something like this:

<module 'MyModule' from '/Users/abarnert/src/test/pkgtest3/MyModule/__init__.pyc'>

If you're using Python 2.7, you can skim over the rest of the documentation until this part:

If you simply want to import a module (potentially within a package) by name, use importlib.import_module().

So, just do that:

import importlib
current_module = importlib.import_module(__name__)
setattr(current_module, 'VarA', 5)

If you need to work with earlier 2.x versions, read the whole section (and for your Python version, not the 2.7 I linked above). The right answer is a bit more complicated, and a bit hacky:

import sys
current_package = importlib.import_module(__name__)
current_module = sys.modules[__name__]
setattr(current_module, 'VarA', 5)

Of course if you're never going to run MyModule/mymodule.py as a top-level script, or execfile it or use custom import logic on it or anything like that, you don't need this complexity in the first place. Someone must have already imported you, so just do this:

import sys
current_module = sys.modules[__name__]
setattr(current_module, 'VarA', 5)

Of course the simplest solution here is:

VarA = 5

… but presumably there's a good reason that won't work in your real code.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top