Хотя 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__
, чтобы получить пути других файлов относительно них.
Принимает необязательные глобальные и локальные аргументы, изменяя их на месте, как execfile
, так что вы можете получить доступ к любым переменным, определенным путем чтения переменных после выполнения.
В отличие от execfile
в Python2, не изменяет текущее пространство имен по умолчанию. Для этого вам нужно явно указать globals()
& locals()
.