2013-06-18 20 views
-3

導入的文件/類,就像標題所說,我得到一組導入,全部導入一個類,全部與腳本運行在同一文件夾中:重新加載/重新導入使用從* import *

from lvl import lvl 
from get import get 
from image import image 
from video import vid 
from video import MLStripper 
from system import system 
from setting import setting 
from listsearch import lists 

python3沒有重裝IIRC但imp.reload(),但它似乎沒有工作,

它只是拋出一個錯誤,說這不是一個模塊(它一類,所以它不't work)

在導入這些類的每個小編輯之後,我需要重新啓動腳本

是否沒有辦法重新加載/重新導入類以顯示編輯的效果,而無需啓動腳本或重寫大部分腳本,以便imp.reload()起作用?

python3,Linux的(但更喜歡,如果還對窗口工作)

EDIT1:

例如:如果我使用:

import system 
system.system.temp() 

它返回:

65°C 

如果我將其更改爲顯示°F並使用imp.reload重新加載它

imp.reload(system) 
system.system.temp() 

它返回:

149°F 

所以,它的工作原理,但如果我使用

import system as _system 
from system import system 
system.temp() 

它返回:

65°C 

然後我改變它顯示°F和使用imp.reload重新加載它

imp.reload(_system) 
from system import system 
system.temp() 

它仍然再次回到

65°C 

但是,如果我這樣調用它:

_system.system.temp() 

其返回

149°F 

IDK爲什麼它這一點,但它是因爲它發生在一個while循環?

編輯2:

文件名:system。潘岳:改試驗後

class system: 
    def temp(): 
    temperature = open("/sys/class/thermal/thermal_zone0/temp","r").read() 
    temperature = temperature[:2] 
    return(temperature+"°C") 

改試驗前通過sys.modules模塊

class system: 
    def temp(): 
    temperature = open("/sys/class/thermal/thermal_zone0/temp","r").read() 
    temperature = temperature[:2] 
    temperature = str(9.0/5.0 * int(temperature) + 32).split(".")[0] 
    return(temperature+"°C") 
+2

爲了將來的參考,如果您使用PEP8風格的命名,您的類將被命名爲Lvl,Image等,並且不會與您的模塊名稱衝突,這會使事情變得更簡單。 – abarnert

+0

好吧,我從來沒有真正使用過Python增強建議,我認爲編寫易於理解和記憶的方式會更好,我儘量減少一切,但要保持它像indents/newlines和變量/函數一樣排序(使用2個空格縮進,如果文件只有幾行,有時候會有1個空格縮進),因爲我的任何代碼都不太可能被其他人使用,基本上任何意思都是由於錯誤的大小寫造成的較小的鍵入和錯誤 –

+2

「我從來沒有真正使用過Python增強建議「沒有任何意義。 PEP是Python 2.0及更高版本中所做重大更改的記錄。請參閱[什麼是PEP?](http://www.python.org/dev/peps/pep-0001/#what-is-a-pep)。無論如何,即使你認爲你的代碼不太可能被另一個人使用,如果你想將它發佈到SO上並尋求幫助,它仍然是很重要的,這對其他人來說是很重要的。最後,創造你自己的命名風格直接導致你的問題 - 在範圍內你不能有兩件名爲'lvl'的東西。 – abarnert

回答

2

您只能reload模塊:

的參數必須是一個模塊對象,因此它必須成功之前進口。

就你而言,你沒有任何對模塊對象的引用。你將不得不import它,即使你不想使用它爲別的,只爲調用reload以後着想。

此外,reload後,你必須重新import名稱:老物件

其他參考資料(如外部模塊名稱)不反彈來引用新的對象和要如果需要的話,在它們出現的每個命名空間中更新。

當你這樣做from foo import bar,那bar是一個「名外部模塊」,所以你必須明確地重新綁定。

如果你仔細想想,它這樣的工作方式。有沒有辦法reload可以枚舉,其定義是依賴於以前版本的模塊來更新他們的所有對象。即使可能,也會有無限循環。如果新版本甚至沒有定義舊版的課程,會發生什麼?或者如果這個類是動態定義的?

從另一方面來看,from foo import barimport foo; bar = foo.bar非常相似。 bar是在您的命名空間,而不是foo的命名空間,所以reload(foo)不會去碰它的名稱;您需要再次複製新的foo.bar

解決所有這些問題的簡單方法是在reload之後重複所有from foo import bar行。


對於簡單的情況:

import video 
from video import MLStripper 

# ... later 

imp.reload(video) 
from video import MLStripper 

然而,大部分的例子有一個明顯的命名衝突:一旦你from video import video,你可以不再reload(video)。因此,您需要對video模塊對象的另一個參考。

Python會圍繞一個給你,你可以使用:

imp.reload(sys.modules['video']) 
from video import MLStripper 

,或者,你可以使用as條款,或只是一個=分配,給它任何你想要的名稱。

import video as _video 
from video import video 

# ... later 

imp.reload(_video) 
from video import video 

從您的意見和你的編輯問題,這聽起來像你有進一步的問題。讓我們用一個簡單的非碰撞案例來討論它。

我相信你實際上在做這樣的事情:

import video 
from video import MLStripper 

stripper = MLStripper('foo") 

# ... later 

imp.reload(video) 
from video import MLStripper 

第一行會成功地重新加載video模塊,並且第二將其MLStripper類複製到全局,因此任何新MLStripper情況下,你創建將是新的類型。

但這並不影響任何現有的MLStripper實例,如stripper

就像MLStripper是,stripper是這些「模塊外部的名稱」之一。但實際上更糟糕。爲了調整它,reload必須弄清楚它的狀態會是什麼狀態,如果新版本的代碼從創建時開始生效。很顯然,這是一個無法解決的問題。


如果你知道你要修補的情況下,可以對付它們有效,你處理的類以同樣的方式:只需再次創建它們:

imp.reload(video) 
from video import MLStripper 
stripper = MLStripper('foo") 

如果這還不夠好,有三種可能性,可能是你想要的:

  • Monkeypatch方法,屬性等進入實例和它們的__class__(es)。
  • 直接修補的情況下,__class__屬性,以便於從類繼承的東西現在是從這個新類繼承。
  • 序列化與pickle的情況下reload前,然後反序列化之後。

對於非常簡單的情況,所有這三種情況都會起作用。對於更復雜的情況,你必須明白你在做什麼。


注意,您可以在一個功能包了很多這方面的東西,但你必須瞭解當地人和全局工作(以及如何導入和重載工作),或者你要結束了自己的困惑。

一個簡單的解決方案是創建「dump all state」和「load all state」函數。然後,您可以轉儲所有內容,退出,重新啓動和恢復。 Python教程和ipython文檔都描述了幾種不同的方法來代替使用reload;這可能值得回顧並重讀這些內容。

+0

它似乎一旦導入,再次執行from * import *命令將不會執行任何操作。 –

+0

@freeforalltousez:它肯定會做一些事情:它將模塊中的名稱重新複製到全局變量。只需重新加載模塊不會那樣做;只是做'from ... import ...'不會重新加載。這就是爲什麼你需要兩個。 – abarnert

+0

我做了兩個和重新加載模塊中的類仍然是舊類,類沒有得到更新,但如果我使用導入視頻,並使用video.video.link(* arg *)調用它,然後做imp.reload(_video),然後與函數鏈接的類得到更新 –

0

訪問,重裝,然後重新分配導入的名稱:

imp.reload(sys.modules['lvl']) 
from lvl import lvl 

imp.reload(sys.modules['get']) 
from get import get 

所有from something import name語法確實是導入something然後將name綁定到相同的對象something.name指的是。

通過使用sys.modules您不必再次顯式導入模塊,並且可以在重新加載後達到用於重新綁定的對象的新定義。

+0

你不需要'sys.modules ['get']。get',你可以(重新)從'get get'獲取''。 – abarnert

+0

@abarnert:確實;更新。 –