2017-01-23 44 views
-1

我想寫一些測試python模塊的包裝。 這個包裝模擬一個環境,然後通過execfile啓動其他python模塊。 有很多python模塊需要測試(> 200)。防止調用子模塊的全局變量在不更改submodul本身的情況下進行更改?

這些模塊內部有一些硬編碼的變量,它們包含一些絕對文件路徑,這些文件路徑在我的模擬環境中不存在(我也無法創建它們)。這些文件路徑是選項文件的路徑,該腳本將讀入。每個模塊總是隻有一個選項 - 文件,並且該選項文件的文件路徑始終保存在同一個全局變量中(我的意思是:變量名稱在每個模塊中都是相同的:optionFile)。

optionFile = "Path to Option file" 

我的想法是,我也許可以在我執行的測試模塊預先設置這個全局變量「optionFile」與現有的路徑。但是,這當然不會有幫助,因爲執行模塊在執行時會用硬編碼值覆蓋「optionFile」。

我想知道是否有一種方法可以覆蓋globals對象的__setattr__函數,所以它對某些變量名不會做任何事情,但是我沒有對我的嘗試做出成功。你認爲這可以工作,並有任何建議嗎?

+1

模塊中代碼的性質是什麼?如果它全部位於模塊的頂層,那麼你可能不太好運。也就是說,如果一個文件具有'optionFile =「/ some/path」',然後在下一行執行了'open(optionFile)',那麼你就不能在'optionFile'中修改值之間。你可能會更好地運用「open」函數(或者模塊用來與'optionFile'交互的任何其他函數)。 – BrenBarn

+0

好的解釋:你所描述的正是python模塊的性質:(。 我怎麼能用open-function? ...來實現它,因爲這實際上可以工作,因爲這些選項文件的所有擴展名都是相同(.opt)。如果我打開函數「重新路由」所有以'.opt'結尾的文件到硬編碼版本(我的替換選項文件),這可能會起作用嗎? – and0r

+0

問題似乎不清楚對我而言,標題要求採取各種方法來防止變量被改變,但是主體要求改變變量的方法? – Goyo

回答

0

基於我們在這裏拿到了第一印象,這似乎是不可能改變全局的__setattr__對象(雖然我不明白爲什麼不...)

因此,答案似乎是「沒有」。

編輯
原因,爲什麼這不起作用,是沒有全球性的「全局」對象。相反,每個模塊都有其具有自己的全局變量的「個人」名稱空間。該名稱空間在模塊加載後創建。當然可以改變這個全局命名空間 - 但是隻有在模塊已經被加載之後(這對我的應用場景沒有幫助)。感謝BrenBarn的澄清。
編輯結束

解決我的具體描述問題的方法是改變Python的內置開放函數。

# Keep original pointer to the actual Open-function 
realOpen = open 

# Overwrite the name of the Open-function to implement own logic 
def open(filename, mode='r'): 
    if filename.endswith(".opt"): 
     print "Rerouting opening command" 
     realOpen("myCentralOptionFile.opt","r") 

    else: 
     realOpen(filename,mode) 

注意:此解決方法與標題無關。

+1

沒有「全局對象」。全局變量存儲在模塊名稱空間中。確實有可能改變這個命名空間,但問題是,直到模塊被加載之後,你才能做到這一點,到那時所有的代碼已經運行並完成了它想用'optionFile'完成的任何事情。你想要的只是運行模塊的一部分(定義'optionFile'的部分),然後「暫停」來改變它的值,但是你不能這麼做。全是或者全無:你要麼運行整個模塊,要麼根本不運行它。 – BrenBarn

相關問題