2013-10-04 16 views
2

爲了添加到我的程序(在Python 2.7中)檢查可用模塊,我添加了以下代碼來代替經典導入(想法是幫助別人找到&添加額外的模塊):python:importlib.import_module(「time」)但時間沒有全局定義

mymodules = ['socket', 'requests', 'simplejson', 'pickle', 'IPy', 
    'pygeoip', 'urllib', 'time', 'urllib2', 'StringIO', 'gzip', 'os'] 

import sys, importlib # these ones should be available, otherwise bad luck :) 
for module in mymodules: 
    try: 
     importlib.import_module(module) 
     print "importing ", module 
    except: 
     if module == "requests": info = "http://docs.python-requests.org/en/latest/user/install/#install or aptitude install python-requests" 
     elif module == "requests": info = "https://github.com/simplejson/simplejson or aptitude install python-simplejson" 
     elif module == "IPy": info = "https://github.com/haypo/python-ipy/wiki or aptitude install python-ipy" 
     elif module == "pygeoip": info = "https://github.com/appliedsec/pygeoip or pip install pygeoip" 
     else: info = "Oops, you should not see this - the description of the missing plugin is missing in the code" 
     print "module {} is missing, see {}".format(module,info) 
     sys.exit(0) 

後來我的程序崩潰,NameError在通話過程中time.time()「時間」沒有定義)。我因此試圖從頭測試模塊導入:

>>> import sys, importlib 
>>> importlib.import_module("time") 
<module 'time' (built-in)> 
>>> print sys.modules.keys() 
['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings', 'abc', 'importlib.sys', 'posixpath', '_weakrefset', 'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 'encodings.__builtin__', '_warnings', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', 'codecs', 'readline', '_sysconfigdata_nd', 'os.path', 'importlib', 'sitecustomize', 'signal', 'traceback', 'linecache', 'posix', 'encodings.aliases', 'time', 'exceptions', 'sre_parse', 'os', '_weakref'] 

time在那裏。然而:

​​

現在有一個經典的進口:

>>> import time 
>>> print time.time() 
1380831191.08 

爲什麼會以這樣的方式不importlib.import_module("time")進口timetime.time()可以叫什麼名字?

+0

你說得對,我可以重新創建它。它不限於'time'模塊,就好像import_module()返回模塊,而不是將其作爲全局導入('time = importlib.import_module(「time」)'將工作) – yuvi

+0

你的代碼:把模塊的url放在一個字典中,這樣你可以查看它們,而不是用多個if語句來檢查名字。此外,不要在第一個失敗的模塊之後退出,但會將缺失的模塊累積在列表中,然後您可以一次通知用戶所有缺失的模塊。另外,應該不需要測試或_dynamically_導入內建模塊,如'os','socket'等 - 只需使用正常的導入語句,如果這些模塊失敗了,您可能會希望看到異常消息,因爲它可能表示嚴重使用python安裝的問題。 – l4mpi

+0

@ l4mpi:感謝您的建設性意見。廣告1:我假設你的意思是一個字典,其中模塊名稱是關鍵字,值是要顯示的信息的值?好主意,我會嘗試。廣告2:也是一個好主意:)廣告3:我最初想到了這一點,然後將所有模塊放在一起以簡化操作。你對這個模塊上的實際失敗(有回溯)的評論是有道理的,也會這樣做。 – WoJ

回答

7

docs

指定的模塊將被插入到sys.modules並返回。

換句話說,import_module不會創建一個變量,你必須做你自己:

time = importlib.import_module('time') 

或者,在你的 「動態」 的情況:

globals()['time'] = importlib.import_module('time') 

在附註中,你甚至爲什麼要這樣做?爲什麼不把正常的import換成try-except區塊?

+1

謝謝 - 它現在完美運作。至於爲什麼不用'try' /'wrap'來包裝'import':我沒有設法讓它接受一個變量(也在這裏討論過)(http://stackoverflow.com/questions/6677424/how-do-我進口值變量封裝功能於蟒蛇,使用可變變量-I樣))。我想過使用'__import__',但[文檔提示importlib](http://docs.python.org/2/library/functions.html#__import__) – WoJ

2

我認爲importlib.import_module("time")返回一個對象,我們需要將它分配給一個變量。使用該變量來調用所有的時間方法。

嘗試:

import sys, importlib 

var_name = importlib.import_module("time") 
print var_name.time() 
-1

請爲上帝之愛不要這樣做,它浪費了一行代碼,它的另一個地方可能存在bug,並且導入系統也會隨時發生變化。它的更好,如果你只是

import requests 

,讓它只是失敗後來我知道,請求丟失,我可以看看有關或安裝它自己。

+0

Downvote - 動態檢查模塊的可用性是一個很好的用例對於'importlib','不這樣做,只是使用靜態導入'並不是完全有用的建議,如果你正在處理大量的模塊(當然你可以在'try/'塊,但爲什麼不只是使用listl和四行與importlib?)。而且「導入系統可能發生變化」在這種情況下顯然是錯誤的 - 「importlib.import_module」將導入一個python模塊的事實不會改變,並且任何影響它的變化都可能會影響'import' 。 – l4mpi

+1

我不介意額外的代碼行,如果我可以幫助某人使用我的模塊,在列表中指出他下一步要去哪裏。 – WoJ

+0

什麼WoJ說。 「讓它失敗,然後我知道請求丟失,我可以自己查看或安裝」並不完全是用戶友好的,並且在某些情況下根本不可接受(例如GUI程序,面向不是程序員的用戶的東西) 。即使作爲一名程序員,我也希望程序能打印出所有_all_丟失模塊的URL列表,並且優雅地退出,而不是像ImportError那樣只爲可能丟失的許多模塊中的第一個崩潰,只給出一個名字, d需要查找(可能比您想象的更難)並安裝。 – l4mpi

相關問題