2016-08-15 52 views
1

之後未定義Python變量我試圖通過使用multiprocessing庫中的Pool查找歷史股票價格數據以查找符號列表。if __name__ =='__main__'

這很好,直到我嘗試使用我回來的數據。我定義了我的hist_price函數,並將其輸出到的列表中。我可以print(pcl)它已完美無瑕,但如果我嘗試print(pcl)if __name__=='__main__':塊,它爆炸說pcl是未定義的。我試過在幾個地方宣佈global pcl,但它沒有什麼區別。

from multiprocessing import Pool 

syms = ['List', 'of', 'symbols'] 

def hist_price(sym): 
    #... lots of code looking up data, calculations, building dicts... 
    stlh = {"Sym": sym, "10D Max": pcmax, "10D Min": pcmin} #simplified 
    return stlh 

#global pcl 
if __name__ == '__main__': 
    pool = Pool(4) 
    #global pcl 
    pcl = pool.map(hist_price, syms) 
    print(pcl) #this works 
    pool.close() 
    pool.join() 

print(pcl) #says pcl is undefined 

#...rest of my code, dependent on pcl... 

我也試圖消除if __name__=='__main__':塊,但它給了我拋出一個RuntimeError告訴我專門把它放回去。是否有其他方法可以調用變量以在if塊之外使用?

+0

你有'if __name __ =='__ main __':'因爲你是從終端運行腳本還是其他原因? –

+0

@MosesKoledoye可能是因爲OP正在使用多處理。 – poke

+0

@poke oh好的。顯然是如此。 –

回答

2

我認爲你的問題有兩個部分。第一個是「當前代碼中pcl有什麼問題?」,第二個是「爲什麼我需要if __name__ == "__main__"防護塊?」。

讓我們按順序解決它們。 pcl變量的問題在於它只在if塊中定義,所以如果模塊在不作爲腳本運行(這是設置​​)的情況下加載,那麼在後面的代碼運行時將不會定義它。

要解決此問題,您可以更改代碼的結構。最簡單的解決方法是防止在if __name__ == "__main__"塊內使用pcl的代碼的其他位(例如,可能會在當前塊下縮進它們)。另一種解決方法是將使用pcl的代碼放入函數中(可以在保護塊外聲明),然後從if __name__ == "__main__"塊中調用函數。這將是這個樣子:

def do_stuff_with_pcl(pcl): 
    print(pcl) 

if __name__ == "__main__": 
    # multiprocessing code, etc 
    pcl = ... 
    do_stuff_with_pcl(pcl) 

至於爲什麼這個問題擺在首位上來,最終的原因是在Windows上使用multiprocessing模塊。您可以在the documentation中閱讀有關該問題。

當多處理爲其Pool創建新進程時,它需要使用當前模塊狀態的副本初始化該進程。由於Windows沒有fork(它將父進程的內存自動複製到子進程中),Python需要從頭開始設置所有內容。在每個子進程中,它從它的文件中加載模塊,並且如果模塊的頂級代碼嘗試創建新的Pool,則會出現遞歸情況,其中每個子進程將開始產生一組全新的它自己的子進程。

multiprocessing代碼具有對一些後衛,我覺得(這樣你就不會fork bomb自己走出簡單的疏忽),但你仍然需要做一些工作你自己的也一樣,通過使用if __name__ == "__main__"警惕任何代碼不應該在子進程中運行。

+0

這個過程在我的代碼的開始附近運行,其餘部分依賴於'pcl'。我希望避免將我的代碼的全部內容放入'if'塊中,如果我能幫到的話。我曾嘗試在'if'塊之外聲明'pcl'(有和沒有'global'),但它仍然看起來將它視爲兩個單獨的實例。 – wampthing2

+0

@ wampthing2:我已經更新了我的答案,以進一步瞭解問題是什麼以及有關如何解決問題的更多詳細信息。排序:不要在頂層做太多的事情,因爲你需要用'if __name__ =='__main __「'來防範。 – Blckknght

相關問題