То, что вы сделали, совсем не то же самое, что execfile
.Поэтому неудивительно, что он не имеет такого же эффекта, как execfile
.
exec
(и execfile
), выполняющий некоторый код непосредственно в текущей области. import
проверяет, загружен ли уже модуль, выполняет код в совершенно новой области, если нет, и затем выдает переменную, содержащую этот объект модуля в текущей области.
Например, допустим, у нас есть файл с именем mod.py
, который выглядит следующим образом:
x = 1
print(x)
Теперь давайте import
it:
>>> import mod
1
>>> mod.x
1
>>> x
NameError: name 'x' is not defined
>>> import mod # nothing will get printed the second and later times
Сравните, что происходиткогда вы execfile
это:
>>> execfile('mod.py')
1
>>> mod.x
NameError: name 'mod' is not defined
>>> x
1
>>> execfile('mod.py')
1
Кроме того, ваш execf
даже не работает по нескольким причинам:
- a.replace(".py", "") не изменяет
a
, просто возвращает новую игнорируемую строку. - Ваш модуль
fibonacci.py
не имеет функции с именем main
. - Вы не можете "перейти к остальной части кода после sys.exit", потому что
sys.exit
выходит из программы.Вы можете справиться с этим с помощью except SystemExit:
, но не должны.Во всяком случае, вы определенно не можете справиться с этим except AttributeError:
;он срабатывает только из-за того, что, например, модуль существует, но не имеет атрибута .main
.
В любом случае, как Что нового в Python3.0 объясняет, что правильный способ сделать execfile
в Python 3 - это open
файл, read
его содержимое и exec
их.Другими словами:
with open(a) as f:
exec(f.read())
Если вы хотите обернуть это в функцию, обратите внимание, что она выполнит код внутри локальной среды этой функции.Если вы хотите выполнить его в глобальных значениях, независимо от того, что, или в среде его вызывающей стороны, или чего-то еще, вам нужно указать это.См. exec
документы для подробностей, но для простого примера:
def execf(a):
with open(a) as f:
exec(f.read(), globals())
В качестве примечания, в редком случае, когда вы действительно делаете нужно делать import
динамически, вы не должны exec
оператор import
, вы должны использовать importlib.import_module
:
try:
mod = importlib.import_module(a)
except ImportError:
# handle that problem
else:
mod.main()