为什么在使用timeit或exec函数时,函数中的变量不会在提供的全局命名空间中搜索?

2024-09-27 14:26:41 发布

您现在位置:Python中文网/ 问答频道 /正文

作为一个简单的例子,我想使用timeitfn函数,该函数内部有一个x变量。因此,我将{'x': 20, 'fn': fn}作为我的全局命名空间传递:

from timeit import timeit

def fn():
    print('This line executed.')
    return x

print(timeit('fn()', globals={'x': 20, 'fn': fn}, number=1_000_000))

我认为因为x不是本地的,Python会检查全局名称空间以找到它。然后我返回"This line executed.",后面是一个名称错误,它说:name 'x' is not defined。但是Python会看到{'x': 20, 'fn': fn}名称空间,因为当我删除'fn': fn部分时,错误会变为name 'fn' is not defined

对于exec函数也是如此(如果这有帮助或有关系):

def fn():
    print('This line executed.')
    return x

s = """def fn():
    print('This line executed.')
    return x"""

exec('fn()', {'x': 10, 'fn': fn})

如何将x引入这些函数?它是将它们定义为模块级变量并将globals()字典传递给global参数的唯一选项吗


2条回答

正如文件所说的^{}

Return a dictionary representing the current global symbol table. This is always the dictionary of the current module (inside a function or method, this is the module where it is "defined", not the module from which it is called).

这专门解决了我的问题。因此,当Python试图在fn函数中查找x时(因为它不是本地的或非本地的),它会找到定义它的位置,并查看函数在中定义的全局名称空间,而不是我们作为全局名称空间提供的全局字典

虽然{'x': 20, 'fn': fn}是Python可以找到标签fn的全局字典,但是fn函数本身没有在那里定义,它在那里被称为

每个模块都有自己的全局变量, 当我们说'fn': fn时,我们的意思是:

  • 在自己的模块中使用fn(例如answer.py),该模块有自己的全局变量

因此,如果在answer.py中没有像x这样的全局变量,fn无法调用它,您将得到NameError

以下是一个例子:

# content of answer.py

x = 10


def k1():
    print(f'{globals()["x"]}')


s = """
print(globals()['x'])
"""

# uses current's module ('answer.py') global variables to run script in `s`
exec(s)

# creates new global variables to run script in `s`
exec(s, {'x': 20})

# uses current's module global variables to call `k1` in module 'answer.py' which has his own global variables
exec('k1()')

# creates new global variables to call `k1` in module 'answer.py' which has his own global variables
# when we say 'k1': k1, it means use `k1` in module 'answer.py' which has his own global variables
exec('k1()', {'k1': k1, 'x': 20})

结果:

10
20
10
10

因此,如果您想让这些函数在全局变量中使用x,您可以选择以下选项:

  • 更改该模块的全局变量
  • 不要使用模块函数,将其写入字符串并将全局变量传递给它

相关问题 更多 >

    热门问题