Что является альтернативой execfile в Python 3?

python python-3.x

197365 просмотра

12 ответа

Кажется, они отменили в Python 3 все простой способ быстро загрузить скрипт, удалив execfile()

Есть ли очевидная альтернатива, по которой я скучаю?

Автор: R S Источник Размещён: 17.05.2019 02:54

Ответы (12)


303 плюса

Решение

Согласно документации , вместо

execfile("./filename") 

использование

exec(open("./filename").read())

Увидеть:

Автор: Pedro Vagner Размещён: 16.05.2013 01:03

194 плюса

Вы просто должны прочитать файл и выполнить код самостоятельно. 2to3 текущий заменяет

execfile("somefile.py", global_vars, local_vars)

как

with open("somefile.py") as f:
    code = compile(f.read(), "somefile.py", 'exec')
    exec(code, global_vars, local_vars)

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

Увидеть:

Автор: Benjamin Peterson Размещён: 13.01.2009 03:20

50 плюса

Хотя exec(open("filename").read())часто приводится в качестве альтернативы execfile("filename"), он пропускает важные детали, которые execfileподдерживаются.

Следующая функция для Python3.x максимально приближена к тому, чтобы иметь такое же поведение, как и непосредственное выполнение файла. Это соответствует бегу python /path/to/somefile.py.

def execfile(filepath, globals=None, locals=None):
    if globals is None:
        globals = {}
    globals.update({
        "__file__": filepath,
        "__name__": "__main__",
    })
    with open(filepath, 'rb') as file:
        exec(compile(file.read(), filepath, 'exec'), globals, locals)

# execute the file
execfile("/path/to/somefile.py")

Заметки:

  • Использует двоичное чтение, чтобы избежать проблем кодирования
  • Гарантированное закрытие файла (Python3.x предупреждает об этом)
  • Определяет __main__, что некоторые скрипты зависят от этого, чтобы проверить, загружаются ли они как модуль или нет, например.if __name__ == "__main__"
  • Параметр __file__лучше подходит для сообщений об исключениях, и некоторые сценарии используют __file__для получения путей к другим файлам относительно них.
  • Принимает необязательные аргументы globals & locals, изменяя их на месте, как это execfileделается, так что вы можете получить доступ к любым переменным, определенным путем чтения переменных после запуска.

  • В отличие от Python2, execfileэто не изменяет текущее пространство имен по умолчанию. Для этого вы должны явно указать globals()& locals().

Автор: ideasman42 Размещён: 15.01.2017 06:08

48 плюса

Как недавно было предложено в списке рассылки python-dev , модуль runpy может быть жизнеспособной альтернативой. Цитата из этого сообщения:

https://docs.python.org/3/library/runpy.html#runpy.run_path

import runpy
file_globals = runpy.run_path("file.py")

Есть тонкие различия execfile:

  • run_pathвсегда создает новое пространство имен. Он выполняет код как модуль, поэтому нет различий между глобальными и локальными (поэтому существует только init_globalsаргумент). Глобалы возвращаются.

    execfileвыполняется в текущем пространстве имен или заданном пространстве имен. Семантика localsи globals, если дано, были похожи на локальные и глобальные переменные внутри определения класса.

  • run_path может выполнять не только файлы, но также яйца и каталоги (подробности см. в документации).

Автор: Jonas Schäfer Размещён: 17.06.2014 10:06

18 плюса

Вы можете написать свою собственную функцию:

def xfile(afile, globalz=None, localz=None):
    with open(afile, "r") as fh:
        exec(fh.read(), globalz, localz)

Если вам действительно нужно ...

Автор: Evan Fosmark Размещён: 12.01.2009 05:38

17 плюса

Этот лучше, так как он берет глобальные и локальные от вызывающей стороны:

import sys
def execfile(filename, globals=None, locals=None):
    if globals is None:
        globals = sys._getframe(1).f_globals
    if locals is None:
        locals = sys._getframe(1).f_locals
    with open(filename, "r") as fh:
        exec(fh.read()+"\n", globals, locals)
Автор: Noam Размещён: 17.05.2010 12:43

11 плюса

Если скрипт, который вы хотите загрузить, находится в том же каталоге, что и тот, который вы запускаете, возможно, «import» выполнит эту работу?

Если вам нужно динамически импортировать код , стоит обратить внимание на встроенную функцию __ import__ и модуль imp .

>>> import sys
>>> sys.path = ['/path/to/script'] + sys.path
>>> __import__('test')
<module 'test' from '/path/to/script/test.pyc'>
>>> __import__('test').run()
'Hello world!'

test.py:

def run():
        return "Hello world!"

Если вы используете Python 3.1 или более позднюю версию , вы также должны взглянуть на importlib .

Автор: ascobol Размещён: 12.01.2009 05:28

7 плюса

Вот что у меня было ( fileуже назначен путь к файлу с исходным кодом в обоих примерах):

execfile(file)

Вот что я заменил:

exec(compile(open(file).read(), file, 'exec'))

Моя любимая часть: вторая версия прекрасно работает как в Python 2, так и в 3, то есть нет необходимости добавлять в зависящую от версии логику.

Автор: ArtOfWarfare Размещён: 07.10.2014 01:39

5 плюса

Обратите внимание, что приведенный выше шаблон не будет работать, если вы используете объявления кодировки PEP-263, которые не являются ascii или utf-8. Вам нужно найти кодировку данных и правильно ее кодировать, прежде чем передать ее в exec ().

class python3Execfile(object):
    def _get_file_encoding(self, filename):
        with open(filename, 'rb') as fp:
            try:
                return tokenize.detect_encoding(fp.readline)[0]
            except SyntaxError:
                return "utf-8"

    def my_execfile(filename):
        globals['__file__'] = filename
        with open(filename, 'r', encoding=self._get_file_encoding(filename)) as fp:
            contents = fp.read()
        if not contents.endswith("\n"):
            # http://bugs.python.org/issue10204
            contents += "\n"
        exec(contents, globals, globals)
Автор: Eric Размещён: 13.04.2011 12:43

3 плюса

Кроме того, хотя вы и не являетесь чистым Python-решением, если вы используете IPython (как вы, вероятно, должны в любом случае), вы можете сделать:

%run /path/to/filename.py

Что одинаково легко.

Автор: R S Размещён: 15.01.2017 06:10

2 плюса

Я просто новичок здесь, так что, может быть, это просто удача, если я нашел это:

После попытки запустить скрипт из приглашения интерпретатора >>> с помощью команды

    execfile('filename.py')

для которого я получил "NameError: имя 'execfile' не определен", я попробовал очень простой

    import filename

это сработало хорошо :-)

Я надеюсь, что это может быть полезным, и спасибо всем за отличные советы, примеры и за все эти виртуозно прокомментированные фрагменты кода, которые вдохновляют новичков!

Я использую Ubuntu 16.014 LTS x64. Python 3.5.2 (по умолчанию, 17 ноября 2016 г., 17:05:23) [GCC 5.4.0 20160609] в Linux

Автор: Claude Размещён: 11.02.2017 11:23

-3 плюса

найдите маршрут установки вашей папки (он у меня есть в C: \ python34), затем выполните на обычной оболочке cmd

   set path=%path%;c:\python34

теперь, когда вы инициализируете оболочку, перейдите в C: \ python34 \ myscripts и используйте классическую команду

 python filename.py 
Автор: Weapon X Размещён: 04.02.2015 08:42
Вопросы из категории :
32x32