views:

45

answers:

3

Hi All:

Suppose I've got 2 different modules which have the uniform(same) interfaces. The files list like this:

root/
   logic.py
   sns_api/
      __init__.py
      facebook/
          pyfacebook.py
          __init__.py
      myspace/
          pymyspace.py
          __init__.py

And 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 the codes, so I'm wondering how can I just set a flag to show which module I use and python will load the right codes automatically, 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 whether using the dynamic importing will work, or eval raw python codes, but seems not a good solution. Or if I can make a uniform wrapper in

sns_api/__init__.py

Anyone can help?

A: 

Have a "factory" function in each module, do dynamic import and call the factory for the loaded module. At least, that's one way to do it. Remember, the pythonic way is "duck typing" so that factory returns an object and the client uses it through "duck calls" :-)

jldupont
+5  A: 

With just two i'd 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. It's done like this in the library, see the os module.

You can do really dynamic imports using name = __import__('module'), but you probably don't need this.

THC4k
A: 

You can also use exec:

exec "from sns_api.%s import Platform" % PLATFORM

Then in your implementation files, assign something to Platform:

# in pyfacebook.py
class Facebook:
   def __init__(self, a, b):
       # do the init
   def method1(self, a, b, ...):
       # do the logic

Platform = Facebook
Ned Batchelder