Load different modules without changing the logical file
Let's say I have two different modules that have the same (same) interfaces. The list of files looks like this:
root/ logic.py sns_api/ __init__.py facebook/ pyfacebook.py __init__.py myspace/ pymyspace.py __init__.py
Both pyfacebook.py and pymyspace.py have the same interfaces, which means:
# in pyfacebook.py
class Facebook:
def __init__(self, a, b):
# do the init
def method1(self, a, b, ...):
# do the logic
# in pymyspace.py
class Myspace:
def __init__(self, a, b):
# do the init
def method1(self, a, b, ...):
# do the logic
Now I have a question. I want to do the logic in logic.py without duplicating codes, so I wonder how I can just set a flag to show which module I am using and python will automatically load the correct codes, which means:
# in logic.py
PLATFORM = "facebook"
# import the right modules in, complete the logic with the current platform
# create the right instance and invoke the right methods
Then I change PLATFORM = 'myspace', the logic will work automatically.
So how can I do this?
I'm wondering if using dynamic imports would work, or eval raw python codes, but doesn't seem to be a good solution. Or if I can create a single wrapper in
sns_api/__init__.py
Anyone can help?
With just two I would do
if platform == 'facebook':
from pyfacebook import FaceBook as Platform
elif platform == 'myspace':
from pymyspace import Myspace as Platform
else:
raise RuntimeError, "not a valid platform"
and use Platform
in the rest of the code. This was done in the library, see module os
.
You can actually import dynamically using , but you probably don't need to.name =
__import__
('module')
Have a "factory" function in each module, do dynamic imports and call factory on the loaded module. At least this is one way to do it. Remember the pythonic way is duck printing, so the factory returns an object and the client uses it via duck calls :-)
You can also use exec:
exec "from sns_api.%s import Platform" % PLATFORM
Then, in your implementation files, assign something to the platform:
# in pyfacebook.py
class Facebook:
def __init__(self, a, b):
# do the init
def method1(self, a, b, ...):
# do the logic
Platform = Facebook