2016-09-30 89 views
0

我有兩個文件。一個是program_utils.py與內容:異常類無法導入

class SomeException(Exception): 
    def __init__(self, *args, **kwargs): 
     Exception.__init__(self, *args, **kwargs) 

另一個,比方說,program.py,與

import program_utils 

def SomeFunction(arg): 
    if arg in set([ok_val1, ok_val2]): 
     # do something 
    else: 
     raise SomeException('reason') 

當我運行program.py它抱怨:NameError: name 'MyException' is not defined。當我將program_utils.py的內容直接粘貼到program.py時,它工作正常。爲什麼?

+3

'import program_utils'並不意味着「將'program_utils'的內容轉儲到我的名字空間中」。您仍然必須以'program_utils.whatever'的身份訪問。 – user2357112

+2

您沒有將名稱導入您的名稱空間,因此您需要將其名稱範圍...'program_utils.SomeException'或導入到您的名稱空間中 - 'from program_utils import SomeException' – AChampion

+0

這應該是顯而易見的。感謝大家的耐心。 – Jason

回答

2

不像#includeC/C++,在蟒蛇的import陳述並不等同於複製/粘貼文件到您的文件。

如果你想要的行爲,你可以排序的做得到它:

from program_utils import * 

不過,也有一些注意事項。例如:如果您要導入一個包,__init__.py中的__all__變量控制哪些符號會在from foo import *處導入。

一般來說,from foo import *不是一個很好的做法。你不一定知道你正在輸入什麼符號。此外,如果您使用多個模塊執行此操作並且它們都定義了相同的符號,則可能會覆蓋某些符號的值。

可以說,如果您在使用模塊名稱時使用符號,它也會更清楚一些。即:

foo.bar() 

VS

from foo import * 
... 
from spam import * 

bar() 

在第二種情況下,它可能不是很明顯,bar從foo的模塊來了。

有一個(小)性能考慮因素。如果你最終做了foo.bar()很多,你實際上在做一個不必要的字典查找,因爲每次翻譯查找'bar'foo.__dict__。要解決這個問題,你可以這樣做:

from foo import bar 
+0

只需注意:導入'*'是一種不好的做法。 [這是爲什麼](http://stackoverflow.com/questions/2386714/why-is-import-bad)。 –