2012-07-09 39 views
1

我有一长串可能需要导入的文件。我只需要其中的一个,它们都具有相同的界面。 (选择支付网关来处理付款)使用变量“插值”创建导入语句

假设我有一个字典表示所有网关文件的名称。

gateways = { 
    '1' : 'authorize', 
    '2' : 'paysimple', 
    '3' : 'braintreepayments', 
    '4' : 'etc', 
} 

我知道的钥匙,根据来自数据库的信息这本词典。所以,如果我收到网关值为1的支付处理请求,我知道它需要由Authorize.net处理。 A 2将由Pay Simple处理。等等

我希望能够创建一个导入语句,该语句使用我所知道的信息而不是一个可怕的清单elif语句。

考虑下面的简单的方法:

# For the purposes of this example assume payment_gateway is defined 
# elsewhere and represents the key to the dictionary 
gateway_file = gateways.get(payment_gateway) 

import_str = "from gateway_interface.%s import process" % gateway_file 
gogo(import_str) 

gogo是一种能够导致导入语句,它实际进口。

这样的事情可能吗?

+2

你确定你的程序只处理一次付款然后退出吗?这听起来不寻常。 – 2012-07-10 00:16:19

+0

我不确定这是多么的不寻常。如果您进行在线购物并要求结账,您为什么要使用多个网关处理交易? – Rico 2012-07-10 15:42:33

+0

您一次只能使用一个,但通常在线购物将由长期运行的流程处理,该流程在其整个生命周期内处理许多请求。 – 2012-07-10 17:32:47

回答

5

最简单的

process = __import__('gateway_interface.'+gateway_file,fromlist=['foo']).process 

编辑:在fromlist里 '富' 可以是任何东西,只要fromlist里是不是的emptyList。在Why does Python's __import__ require fromlist?中解释了一点点奇怪。

我也必须编辑,因为在我的第一篇文章__import__未按预期工作,如Python's __import__ doesn't work as expected中进一步描述。

,如果你有蟒蛇2.7

import importlib 
process = importlib.import_module('gateway_interface.'+gateway_file).process 

WAAAAY酷是使用package_tools(如from pkg_resources import iter_entry_points

这可能给你一个解决方案,找到合适的功能,即使他们是在奇包不在gateway_interface下。如果他们都在一个地方,并且你不需要那种过度杀伤的细节点,那么......是的,只是__import__

+0

这并不适合我,我不确定我做错了什么。我得到以下错误:''模块'对象没有'process''属性 – Rico 2012-07-10 15:39:51

+0

我会测试,不知道你试过两种方法中的哪一种。在gateway_file子目录中是否有'__init __。py'? – 2012-07-10 15:49:40

+0

一切都在同一个模块'gateway_interface'内。我需要导入的文件有一个名为'process'的类,我需要实例化。是的,'gateway_interface'有'__init __。py'。 – Rico 2012-07-10 16:30:02

2

查看imp模块,该模块允许您访问import语句的内部或__import__方法本身 - 它们中的任何一个都应该允许您实现您所描述的内容。

1

的内置__import__方法应该工作:

process = __import__(gateways.get(payment_gateway)).process 
相关问题