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



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



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

766   12  

12 ответов:

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

execfile("./filename") 

использовать

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

посмотреть:

вы просто должны прочитать файл и выполнить код самостоятельно. 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)

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

посмотреть:

как предложил на 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 всегда создает новое пространство имен. Он выполняет код как модуль, поэтому нет разница между глобалами и местными жителями (именно поэтому есть только

пока 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.икс предупреждает об этом)
  • определяет __main__, некоторые скрипты зависят от этого, чтобы проверить, загружаются ли они как модуль или нет, например. if __name__ == "__main__"
  • задание __file__ лучше для сообщений об исключениях и некоторые скрипты используют __file__ чтобы получить пути других файлов относительно них.
  • принимает необязательные глобальные и локальные аргументы, изменяя их на месте как execfile делает - так что вы можете получить доступ к любым переменным, определенным путем считывания переменных после бегущий.

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

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

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

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

Это лучше, так как он принимает глобальные и местные жители от абонента:

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)

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

Если вам нужно динамически импортировать код встроенной функции _ _ import__ и блок ИМП стоит посмотреть.

>>> 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.

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

execfile(file)

вот что Я заменил его:

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

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

обратите внимание, что приведенный выше шаблон завершится неудачей, если вы используете объявления кодировки 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)

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

%run /path/to/filename.py

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

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

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

    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

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

   set path=%path%;c:\python34

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

 python filename.py 

Comments

    Ничего не найдено.