Похоже, они отменили в Python 3 все простой способ быстро загрузить скрипт, удалив execfile()
Есть ли очевидная альтернатива, по которой я скучаю?
Похоже, они отменили в Python 3 все простой способ быстро загрузить скрипт, удалив execfile()
Есть ли очевидная альтернатива, по которой я скучаю?
reload
вернулся, так какimp.reload
, начиная с 3.2.%run script_name
работает со всеми версиями Python.imp
естьimportlib
(который должен быть импортирован):importlib.reload(mod_name)
импортирует и выполняетmod_name
.runfile()
так как мне нужно было запустить скрипт Python, который выполняется в своем собственном пространстве имен (в отличие от выполнения в вызывающем пространстве имен). Мое приложение: добавьте каталог вызываемого скрипта в системный путь (sys.path
) с помощью__file__
атрибута: если мы используемexecfile()
или его эквивалент в Python 3 (exec(open('file.py').read())
), включенный скрипт запускается в пространстве имен вызывающего и, следовательно,__file__
преобразуется в имя вызывающего файла.Ответы:
Согласно документации , вместо
использование
Видеть:
источник
close
этот дескриптор файла. Еще одна причина, чтобы не нравиться изменения с Python 2.Вы просто должны прочитать файл и выполнить код самостоятельно. 2to3 текущий заменяет
в виде
(Вызов компиляции не является строго необходимым, но он связывает имя файла с объектом кода, что немного облегчает отладку.)
Видеть:
источник
exec
что это утверждение в python2, оноexec(code)
работает, потому что парены просто игнорируются."somefile.py"
содержалиinspect.getsourcefile(lambda _: None)
который терпел неудачу без Компилировать, потому чтоinspect
модуль не может определить , где код был откуда.open("somefile.py")
может быть неправильным, еслиsomefile.py
используется кодировка символов, отличная отlocale.getpreferredencoding()
.tokenize.open()
может быть использован вместоХотя
exec(open("filename").read())
часто приводится в качестве альтернативыexecfile("filename")
, он пропускает важные детали, которыеexecfile
поддерживаются.Следующая функция для Python3.x максимально приближена к тому, чтобы иметь такое же поведение, как и непосредственное выполнение файла. Это соответствует бегу
python /path/to/somefile.py
.Ноты:
__main__
, что некоторые скрипты зависят от этого, чтобы проверить, загружаются ли они как модуль или нет, например.if __name__ == "__main__"
__file__
лучше подходит для сообщений об исключениях, и некоторые сценарии используют__file__
для получения путей к другим файлам относительно них.Принимает необязательные аргументы globals & locals, изменяя их на месте, как это
execfile
делается, так что вы можете получить доступ к любым переменным, определенным путем чтения переменных после запуска.В отличие от Python2,
execfile
это не изменяет текущее пространство имен по умолчанию. Для этого вы должны явно указатьglobals()
&locals()
.источник
Как недавно было предложено в списке рассылки python-dev , модуль runpy может быть жизнеспособной альтернативой. Цитата из этого сообщения:
Есть тонкие различия в
execfile
:run_path
всегда создает новое пространство имен. Он выполняет код как модуль, поэтому нет различий между глобальными и локальными (поэтому есть толькоinit_globals
аргумент). Глобалы возвращаются.execfile
выполняется в текущем пространстве имен или заданном пространстве имен. Семантикаlocals
иglobals
, если дано, были похожи на локальные и глобальные переменные внутри определения класса.run_path
может выполнять не только файлы, но также яйца и каталоги (подробности см. в документации).источник
file_globals
? Это избавит от необходимости вводитьfile_globals['...']
для каждой переменной.Этот лучше, так как он берет глобальные и локальные от вызывающей стороны:
источник
execfile
. Это даже сработало для меня при использовании pytests, где другие решения, опубликованные выше, потерпели неудачу. Спасибо! :)Вы можете написать свою собственную функцию:
Если вам действительно нужно ...
источник
globals
иlocals
указывают на глобальное пространство имен для модуля, содержащего определение,execfile()
а не на глобальное и локальное пространство имен вызывающей стороны. Правильный подход состоит в том, чтобы использовать вNone
качестве значения по умолчанию и определять глобальные и локальные значения вызывающего абонента с помощью возможностей самоанализаinspect
модуля.Если скрипт, который вы хотите загрузить, находится в том же каталоге, что и тот, который вы запускаете, возможно, «import» выполнит эту работу?
Если вам нужно динамически импортировать код , стоит обратить внимание на встроенную функцию __ import__ и модуль imp .
test.py:
Если вы используете Python 3.1 или более позднюю версию , вы также должны взглянуть на importlib .
источник
importlib
dev.to/0xcrypto/dynamic-importing-stuff-in-python--1805Вот что у меня было (
file
уже назначен путь к файлу с исходным кодом в обоих примерах):Вот что я заменил:
Моя любимая часть: вторая версия прекрасно работает как в Python 2, так и в 3, то есть нет необходимости добавлять в зависящую от версии логику.
источник
Обратите внимание, что приведенный выше шаблон не будет работать, если вы используете объявления кодировки PEP-263, которые не являются ascii или utf-8. Вам нужно найти кодировку данных и правильно ее кодировать, прежде чем передать ее в exec ().
источник
Кроме того, хотя вы и не являетесь чистым Python-решением, если вы используете IPython (как вам, вероятно, следует в любом случае), вы можете сделать:
Что одинаково легко.
источник
Я просто новичок здесь, так что, может быть, это просто удача, если я нашел это:
После попытки запустить скрипт из приглашения интерпретатора >>> с помощью команды
для которого я получил "NameError: имя 'execfile' не определено", я попробовал очень простой
это сработало хорошо :-)
Я надеюсь, что это может быть полезным, и спасибо всем за отличные советы, примеры и все эти виртуозно прокомментированные фрагменты кода, которые вдохновляют новичков!
Я использую Ubuntu 16.014 LTS x64. Python 3.5.2 (по умолчанию, 17 ноября 2016 г., 17:05:23) [GCC 5.4.0 20160609] в Linux
источник
Для меня самый чистый подход - использовать
importlib
и импортировать файл как модуль по пути, например так:Пример использования
Давайте иметь файл
foo.py
:Теперь просто импортируйте и используйте его как обычный модуль:
Я предпочитаю эту технику по сравнению с прямыми подходами, например,
exec(open(...))
потому что она не загромождает ваши пространства имен или излишне портит$PATH
.источник