I have the following mis-fortunate situation:
Three directories (A, B and C) contain a python module M with a function F. (Those directories are not packages and it is impossible to change anything about the situation.)
I am looking for a way to import them separately to access their functionalities. How do I need to import those modules to access F somewhat like this:
A.F()
B.F()
C.F()
-
1user from a.M import F as A_Ftimger– timger2011年09月14日 14:04:28 +00:00Commented Sep 14, 2011 at 14:04
-
I'm curious about how you got into this f0rked up situation, why can't you solve it the 'proper' way and now have to hack something together?wim– wim2011年09月14日 15:08:40 +00:00Commented Sep 14, 2011 at 15:08
-
@wim The f0rked up situation is a dependency and you do not want to change things in a dependency or you will end up messing up the interface which leads to god knows what... This is why I am looking for a 'proper' way at least on my side of the interface.Woltan– Woltan2011年09月15日 06:49:50 +00:00Commented Sep 15, 2011 at 6:49
-
Duplicate of How to import a module given the full path?Piotr Dobrogost– Piotr Dobrogost2012年01月22日 21:56:21 +00:00Commented Jan 22, 2012 at 21:56
4 Answers 4
You need to exec things into a new locals dictionary. You can only get to the files you mention as files, not as modules, then stuff them into a moduletype.
from types import ModuleType
with open("A/M.py") as a:
A = ModuleType('A')
exec a.read() in A.__dict__
with open("B/M.py") as b:
B = ModuleType('B')
exec b.read() in B.__dict__
with open("C/M.py") as c:
C = ModuleType('C')
exec c.read() in C.__dict__
Then access them like B.F() as you wanted. The only problem is the module metadata isn't set up correctly, so it will appear as a builtin. You can even then do:
import sys
sys.modules['A'] = A
sys.modules['B'] = B
sys.modules['C'] = C
and they will be importable like import A from other parts of your application.
1 Comment
This will work, but it seems a bit inelegant...
import sys
sys.path.append("A")
import M as A
sys.path.pop()
del sys.modules['M']
sys.path.append("B")
import M as B
and so on...
4 Comments
pre_path point always to sys.path so changing sys.path will change pre_path. What you should do is each time pop() from sys.path after you finish importing.M in B is not loaded with import M as B if previously import M as A was imported. If I call F of B with B.F() actually the function F in A is called.sys.modules['M'] after importing it, because the next time you try to import the other module M the import will be skipped because it's already in sys.modules.put an __init__.py in each A/ B/ and C/. The content of this file is
from M import F
Than the following code should work:
import A, B, C
A.F()
B.F()
C.F()
The __init__.py declares the directory as a package, and the statements in this file are executed when you import the package.
1 Comment
__init__.py can be added to make it a package.use import as like
from A.M import F as A_F