2012-07-09 79 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