2016-09-30 3 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

В отличие от #include в C/C++, в питона import заявление не эквивалентно копировать/вставить файл в файл.

Если вы хотите, что поведение, вы можете сортировать получить его, выполнив:

from program_utils import * 

Однако, есть некоторые оговорки. например: если вы импортируете пакет, переменная __all__ в __init__.py контролирует, какие символы импортируются whtin, делая from foo import *.

В общем, from foo import * не очень хорошая практика. Вы не обязательно знаете, какие символы вы импортируете. Кроме того, вы можете перезаписать значение некоторых символов, если вы делаете это с несколькими модулями, и оба они определяют один и тот же символ (символы).

Возможно, также более понятно, что происходит, если вы используете имя модуля при использовании его символов. т.е .:

foo.bar() 

против

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). –

Смежные вопросы