2016-05-06 8 views
3

Я полагаю, что это общий вопрос, так что извините, если не отправлен в нужном месте.python import несколько раз

Скажем, например, у меня есть функция a, которая импортирует os. Если бы я несколько раз вызывал эту функцию из другого файла, я предполагаю, что импорт будет выполняться несколько раз? Есть ли способ импортировать модуль, если он еще не присутствует?

В принципе, у меня есть класс, который вызывает несколько функций, импортированных из разных файлов, вместо импорта всего файла я думал, что будет проще импортировать только функцию, но теперь мне интересно, буду ли я давать себе головные боли в в долгосрочной перспективе с избытком импорта.

+0

Самый большой вопрос, почему вы импортируете внутри функции, а не вверху файла? Практически нет оснований для этого, и это - запах кода. –

+2

Python кэширует импортированные модули и не импортирует их дважды. –

+0

Я импортировал только функцию из модуля, поэтому, чтобы избежать ошибок, я включил импорт в эту функцию, предполагая, что я должен импортировать весь файл и просто вызвать функцию как обычно? – JONAS402

ответ

10

Как described в питоне документации, когда питон увидеть некоторый оператор импорта он делает следующие вещи:

  • проверяют некоторые глобальные таблицы, если модуль уже импортирован
    • если модуль не импортированный импорт питона это , создает объект модуля и помещает вновь созданный объект модуля в глобальную таблицу
    • если модуль импортирован, python просто получает объект модуля
  • когда питон имеет модульный объект он связывает его с именем, которое вы выбрали
    • если это import foo имя для модуля foo будет foo
    • если это import foo as bar имя для модуля foo будет bar
    • если это было from foo import bar as baz python находит функцию (или что-то еще) bar в модуле foo и будет связывать эту функцию, чтобы назвать baz

Таким образом, каждый модуль импортируется только один раз.

Чтобы лучше понять импортную механику, я бы предложил создать игрушечный пример.

Файл module.py:

print("import is in progress") 

def foo(): 
    pass 

Файл main.py:

def foo(): 
    print("before importing module") 
    import module 
    module.foo() 
    print("after importing module") 

if __name__ == '__main__': 
    foo() 
    foo() 

Помещенный выше файлов в тот же каталог. Когда module.py импортируется, он печатает import is in progress. При запуске main.py он будет пытаться импортировать module несколько раз, но результат будет:

before importing module 
import is in progress 
after importing module 
before importing module 
after importing module 

Так импорт действительно происходит только один раз. Вы можете настроить этот пример игрушек, чтобы проверить интересующие вас случаи.

+0

Блестящее описание, очень полезные ребята, спасибо тонне! – JONAS402

+0

Отлично, очень ясно. Еще одна вещь должна быть осторожной. Если позже вы импортируете модуль в a с ** как **, например 'from module import foo as new_name', предыдущее имя модуля будет закрыто, показывает, что' global name 'module' не определен' – evan912