Как я могу использовать тот же импорт из другого скрипта? - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть script1.py, который имеет

from itertools import izip_longest, islice

и где-то в script1.py используется islice.

У меня есть другой скрипт, script2.py, который должен автоматически выполняться в script1.py, поскольку выходной файл script1 является входным файлом script2. Проблема в том, что script2 также необходимо использовать islice. Есть ли способ использовать его, не импортируя islice снова в script2?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Питонический способ использования islice в script2 - это

from itertools import islice

Механизм импорта в Python довольно умный.Импорт модуля не загружает модуль автоматически каждый раз.Первый шаг - всегда проверять, находится ли модуль в sys.modules.Если это так (как это было бы в вашем случае), соответствующие существующие ссылки привязаны к именам в вашем пространстве имен.

Давайте рассмотрим конкретный пример с двумя модулями ниже:

mod1.py

from itertools import izip_longest, islice
from mod2 import some_function

# code that uses islice and some_function

mod2.py

from itertools import islice

def some_function():
     # do the thing

Если вы запустите mod1,произойдет следующая (отредактированная) последовательность событий:

  1. Создайте пустой объект модуля и зарегистрируйте / кэшируйте его в sys.modules['mod1'] или sys.modules['__main__'], в зависимости от того, как вы запустите скрипт.
  2. Начните выполнение кода в mod1.py.
  3. Проверьте, есть ли itertools в sys.modules: это не
    1. Сделайте некоторую магию, чтобы найти, зарегистрировать и загрузить itertools в sys.modules['itertools']
    2. Добавьте атрибуты izip_longest и islice в ваше глобальное пространство имен в неполном mod1
  4. Проверьте, находится ли mod2 в sys.modules: это не
    1. Сделайте немного магии, чтобы найти mod2 и создайте пустой sys.modules['mod2']
    2. Начните выполнение кода в mod2.py.
    3. Проверьте, если itertoolsнаходится в sys.modules: это
    4. Добавьте атрибут islice в ваше глобальное пространство имен в неполном mod2.Это в основном эквивалентно выполнению islice = sys.modules['itertools'].islice на данный момент.Здесь ничего не загружается.
    5. Выполните оператор def, чтобы создать объект функции, и добавьте его в глобальное пространство имен mod2 с именем some_func.
    6. mod2 isтеперь полностью загружен
  5. Выполните оставшийся код в mod1

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

Официальную документацию о всей процедуре можно прочитать здесь: https://docs.python.org/2/reference/simple_stmts.html#the-import-statement. Эта последовательность событий была в одном месте.реализация или другая, начиная с версии 2.0: https://docs.python.org/2.0/ref/import.html. Вы также можете прочитать больше о том, как модули работают в целом, здесь: https://docs.python.org/2/tutorial/modules.html. Как правило, я нашел официальные документылучший учитель Python за пределами, возможно, переполнение стека.

Еще одна вещь, которую нужно помнить, это то, что модули не разделяют пространства имен.Глобальные переменные внутри модуля - это просто атрибуты этого конкретного объекта модуля.Тем не менее, вы можете сделать что-то вроде этого:

mod2.py

from itertools import islice

def some_function(): pass

mod1.py

import mod2

#use mod2.some_function and mod2.islice as attributes of mod2

Таким образом, у вас есть только один явный импорт islice.Я не считаю это очень питонным подходом.Один из ключевых принципов Python - «явное лучше, чем неявное», и удобочитаемость важнее краткости.Когда вы используете mod2.islice, для читателя подразумевается, что mod2 определяет версию функции, которая отличается от встроенной.

В качестве отступления, рассмотрите возможность перехода на Python 3.6+ в ближайшее время.,Есть много улучшений и новых функций.Python 2.x не будет поддерживаться намного дольше, и многие популярные сторонние библиотеки, такие как numpy, полностью прекратят поддержку Python 2 в следующих выпусках.

0 голосов
/ 15 ноября 2018

Что вы можете сделать здесь - это импортировать * из скрипта1, что также будет включать в себя и весь его импорт. Как то так:

# in script2.py
from script1 import *

Таким образом, вы должны выполнить импорт только один раз. Это то, что вы имеете в виду?

...