先看一段代码:这里在a()函数里定义了一个全局变量a1,后面的调用和修改都没有任何问题。
def a():
global a1 # 定义一个全局变量a1
a1 = int
def b():
global a1
a1 = 100
if __name__ == '__main__':
a()
print(a1)
a1 = 1
print(a1)
b()
print(a1)
# 运行结果:
# <class 'int'>
# 1
# 100
现在把a()函数里用exec()函数来取代实际的语句:出现了变量未定义的错误提示。原因未知,也没有在网上搜到合理的解释。
def a():
exec("global a1")
exec("a1 = int")
if __name__ == '__main__':
a()
print(a1)
# 运行结果:Traceback (most recent call last):
# File "E:\test3.py", line 9, in <module>
# print(a1)
# NameError: name 'a1' is not defined
如果将exec()函数不放到子函数的语句中,是可以的,比如:
if __name__ == '__main__':
exec("global a1")
exec("a1 = int")
print(a1)
a1 = 100
print(a1)
或者:
exec("global a1")
exec("a1 = int")
if __name__ == '__main__':
print(a1)
a1 = 100
print(a1)
# <class 'int'>
# 100
但是这样的话就无法将使用exec()函数创建变量的方法封装以供方便调用。例如要创建10个bool变量b0-b9,就有以下代码:
def a():
global b0
b0 = True
if __name__ == '__main__':
for i in range(10):
exec('global b' + str(i))
exec('b' + str(i) + ' = bool')
# print(globals())
print(b0)
a()
print(b0)
# <class 'bool'>
# True
无法将
for i in range(10):
exec('global b' + str(i))
exec('b' + str(i) + ' = bool')
这一段代码进行封装
如果使用定义类的方法来间接实现:
class A: # 这是一个类似于全局变量的类
for i in range(10):
exec('b' + str(i) + ' = bool')
def b():
A.b0 = True # 调用和修改A类中的变量
if __name__ == '__main__':
print(A.b0) # <class 'bool'>
b()
print(A.b0) # True
如果使用定义外部函数的方法来间接实现:
新建test.py:输入以下代码
for i in range(10):
exec('b' + str(i) + ' = bool')
在主程序中调用上面定义的变量:
import test as A # 导入定义变量的类
def b():
A.b0 = True # 调用和修改类中的变量
if __name__ == '__main__':
print(A.b0) # <class 'bool'>
b()
print(A.b0) # True
使用这两种方法都可以实现在主函数中间接地调用封装好的含有exec()函数的方法。有没有更好的方法,很希望高手指点!
如果使用定义外部函数的方法,但又不希望出现A.b0这种写法,希望如同真正的全局变量那样直接使用b0,可以在主函数内将其全部声明为global来实现。代码如下:
新建test.py,输入以下代码:
tags = []
for i in range(11):
exec('b' + str(i) + ' = int')
exec('tags.append(\'b' + str(i) + '\')')
主程序的代码:
from test import * # 导入外部定义的变量
def b():
global b0
b0 = 200 # 调用和修改变量
if __name__ == '__main__':
for t in tags:
exec('global ' + t) # 将导入的外部定义变量全部声明为全局变量
print(b8) # <class 'bool'>
b5 = 1
print(b5) # 1
b()
print(b0) # 200