Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 3, 2009 12:27:47

anthonio
От:
Зарегистрирован: 2009-06-08
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Где лучше делать import?

Имеем модуль, который никогда не будет запускаться, а из него будут выдёргиваться нужные функции. Эти функции также используют внешние модули/функции. Есть ли существенная разница в чём-либо (может в скорости) где происходит импорт этих внешних модулей, в начале (глобальное пространство имён) или непосредственно перед использованием в теле функции?
Так:

from blablabla import bla

def blo(*args, **kwargs):
bla()
...
или так

def blo(*args, **kwargs):
from blablabla import bla
bla()
...
Аргументируте свою точку зрения! :)



Офлайн

#2 Сен. 3, 2009 13:06:51

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Где лучше делать import?

В функциях, имена сначала ищется в локальном пространстве имен, затем в глобальном. Поэтому с точки зрения производительности, второй вариант быстрее (мы говорим о каких то микросекундах). Но, лучше все же импортировать все модули в начале программы, так как будет меньше путаницы и трудно уловимых ошибок.



Офлайн

#3 Сен. 3, 2009 15:11:51

j2a
От:
Зарегистрирован: 2006-06-29
Сообщения: 869
Репутация: +  1  -
Профиль   Отправить e-mail  

Где лучше делать import?

Зависит от. Предпочитаю 1. По ситуации (слишком много мелких функций с разными импортами, циклические импорты и пр.) – 2.

про миллисекунды и скорость – это _обязательно_ нужно тестировать, потому что если функцию blo вызывают чёрти-сколько-раз, то не факт, что import+local lookup будет быстрее чем global lookup. Если же в функции blo чёрти-сколько-раз вызывается bla, то да – второй вариант быстрее.



Офлайн

#4 Сен. 3, 2009 16:18:14

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Где лучше делать import?

igor.kaist, кажется, несколько погорячился.
Function call (который делается на опкод IMPORT_NAME при вызове __import__) значительно дороже dictionary lookup - даже если учесть тот факт, что все последующие импорты происходят довольно быстро и модуль находится в sys.modules.
К тому же на момент импорта происходит import lock - щелкает мьютекс, переключается PyEval_SaveThread/PyEval_RestoreThread. Долго.

И это не самое страшное. У меня была как-то неприятная проблема - в мультипоточном приложении была взаимная блокмровка на этот самый import lock. Выяснял проблему долго и мучительно. Тем более что она нестабильно воспроизводилась (а если честно - то вообще долгое время по свински всплывала только у пользователей и не хотела проявляться на девелоперских машинах).

Импорт из функции хоть и возможен - но использовать его стоит аккуратно.

Для того, чтобы не тянуть все сразу, используют другие техники.
Можно посмотреть на bzrlib.lazy_import или mercurial.demandimport

Да, еще - при
from mod import name
модуль тянется весь целиком.
Сначала идет IMPORT_NAME, потом IMPORT_FROM.
Если в подуле много мелких функций - то первое обращение затянет их все, как ни старайся.



Отредактировано (Сен. 3, 2009 16:22:06)

Офлайн

#5 Сен. 3, 2009 16:57:31

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Где лучше делать import?

Андрей Светлов, я,честно, несколько раз перечитывал ваше сообщение, но знаний не хватило понять, что же вы хотели сказать. Что быстрее то в итоге? :) // вот что значит настолько глубокие знания…



Офлайн

#6 Сен. 3, 2009 17:13:52

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Где лучше делать import?

Вариант номер раз.
Чтобы программа не тянула все модули сразу - можно попробовать использовать demandimport.py из Mercurial HG.
Работает так: на import statement возвращается прокси, который будет делать импорт при первом реальном обращении.
Подход имеет несколько мелких ограничений (прокси - не модуль и проверка на isinstance не сработает) - но обычно вполне гож.
Поможет ускорить запуск программы - т.е. время до того, как на экране появится что-нибудь, веселящее пользователя своим видом.
Но это уже несколько другая задача.

Пятнадцать минут “аргументировал свою точку зрения” - а оказывается нужно было только пальцем ткнуть. :)



Офлайн

#7 Сен. 4, 2009 03:09:08

anthonio
От:
Зарегистрирован: 2009-06-08
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Где лучше делать import?

Что ж, спасибо всем, а Андрею Светлову – отдельная благодарность :)



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version