首页 > 解决方案 > 执行时跨程序同步变量

问题描述

我正在尝试创建一个基本模块,将execfile函数从 Python 2.* 添加到 Python3(使用函数execf(a))。该模块利用导入来运行 .py 文件,使用如下所示:

import fibonacci 
# From a fibonacci.py file

fibonacci.main()
# Running the program

我通过在多个实例中使用该exec函数来读取文件名并将其插入到这些函数和字符串中,从而利用了这一点。

这是模块(称为execfile)的样子:

def execf(a):
  try:
    a.replace(".py", "") #removes '.py' from filename for use in exec functions
    exec('import {}'.format(a)) #imports the specified file
    exec('{}.main()'.format(a)) #runs the specified file
  except AttributeError:
    pass # Proceeds to rest of code after a sys.exit()
  except ModuleNotFoundError:
    pass # Proceeds to rest of code after program end

这是的内容fibonacci.py

def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

n = int(input("Enter number of terms:"))
print("Fibonacci sequence:")
for i in range(n):
    print(fibonacci(i))

这是main.py(我执行的初始脚本):

from execfile import execf

execf('fibonacci.py')
print("That was " + a + " numbers of the Fibonacci sequence.")

我想要发生的是文件中的a变量fibonacci.py可以在main.py文件中使用,以便我可以打印它,这应该可用于脚本中的所有变量。有没有办法修改全局变量或在全局范围内执行函数,main.py以便可以在文件main.py之后使用变量execf

我考虑在评论中添加一些可以扫描的内容,并检测需要添加到全局范围的变量。就像是:

# fibonacci.py

...

#-;- variables: {"foo": bar, "baz": boo} -;-



# execfile.py

variables = scan_for_variables(script)

但我找不到任何关于如何让 Python “查找”这些变量的信息。如果您有任何问题,请告诉我,谢谢!

标签: pythonpython-3.xvariables

解决方案


你所做的和你做的完全不一样execfile。因此,它没有与execfile.

  • exec(and execfile) 直接在当前范围内执行一些代码。
  • import检查模块是否已经加载,如果没有,则在全新的范围内执行其代码,然后为您提供一个在当前范围内保存该模块对象的变量。

例如,假设我们有一个名为的文件mod.py,如下所示:

x = 1
print(x)

现在,让我们import开始吧:

>>> 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", "") 不会 mutate a,它只会返回一个您忽略的新字符串。
  • 您的fibonacci.py模块没有名为main.
  • 您不能“在 sys.exit 之后继续执行其余代码”,因为sys.exit退出了程序。你可以用 处理这个except SystemExit:,但你不应该。无论如何,你绝对不能用except AttributeError:; 这只会触发,例如,模块存在但没有.main属性的事实。

无论如何,正如Python 3.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声明execimport您应该使用importlib.import_module

try:
    mod = importlib.import_module(a)
except ImportError:
    # handle that problem
else:
    mod.main()

推荐阅读