小白在之前文章中有分享过exec的使用方式,这篇文章中,小白总结一下exec的高阶用法。
先看一个遍历:
for i in range(10):
print ("the result of i is: %d" % (i))
很明显结果为:
the result of i is: 0
the result of i is: 1
the result of i is: 2
the result of i is: 3
the result of i is: 4
the result of i is: 5
the result of i is: 6
the result of i is: 7
the result of i is: 8
the result of i is: 9
上面这种形式,怎样用exec实现呢?
exec ("""for i in range(10):
print ("the result of i : %d" % (i))
""")
结果一样,也是:
the result of i : 0
the result of i : 1
the result of i : 2
the result of i : 3
the result of i : 4
the result of i : 5
the result of i : 6
the result of i : 7
the result of i : 8
the result of i : 9
可能有人会说,这不是比之前更麻烦了么,直接用for循环多方便呀,小白之前也是这样觉得,但是有以下场景时,就会发现这个方法的魅力。
这里我们首先定义了一个expr方法,然后再生名一个方法func,来调用上面的方法。
值得一提的是,这里面隐含了参数的传递以及局部变量和全局变量的关系,相信大家也遇到过类似的问题。
剖析下这段代码:
首先,a是全局变量,作用于整段代码,从结果也可以看出来,输出的结果a是5,但是在输出b和c时都报错了,下面代码以b为例输出了报错结果。
a = 5
expr = """
h = 3
Trapezoidal_area = (a+b)*h/2
print('the a is %s,the b is %s,the h is %s'%(a,b,h))
print(Trapezoidal_area)
print('-----------------------------------')
"""
def func():
b = 10
exec(expr)
exec(expr, {'a': 3, 'b': 4})
exec(expr, {'a': 3, 'b': 4}, {'b': 30, 'h': 40})
func()
print (a,b,c)
#result
the a is 5,the b is 10,the h is 3
22.5
-----------------------------------
the a is 3,the b is 4,the h is 3
10.5
-----------------------------------
the a is 3,the b is 30,the h is 3
49.5
-----------------------------------
NameError: name 'b' is not defined
其次,b是一个作用于func函数的局部变量,假如对代码做一个小修改,在func中输出b:可以看到结果是10,也印证了,在func函数中,b是全局变量
a = 5
expr = """
h = 3
Trapezoidal_area = (a+b)*h/2
print('the a is %s,the b is %s,the h is %s'%(a,b,h))
print(Trapezoidal_area)
print('-----------------------------------')
"""
def func():
b = 10
exec(expr)
exec(expr, {'a': 3, 'b': 4})
exec(expr, {'a': 3, 'b': 4}, {'b': 30, 'h': 40})
print (b)
func()
#result
10
然后,对于h,h是一个在expr中的全局变量,这个在第一步输出结果中也可以看到,虽然第三个传入了h,但是并没有起作用。
而且,也可以看到,exec可以传入两个列表,如果第二个中有和第一个一样的参数,就以第二个为准,如果没有,以第一个为准,这也是exec和eval的一个区别,eval只能传入一个参数组。
需要注意的是exec最多传入三个参数,如果像下面形式,就会报错:
a = 5
expr = """
h = 3
Trapezoidal_area = (a+b)*h/2
print('the a is %s,the b is %s,the h is %s'%(a,b,h))
print(Trapezoidal_area)
print('-----------------------------------')
"""
def func():
b = 10
exec(expr)
exec(expr, {'a': 3, 'b': 4})
exec(expr, {'a': 3, 'b': 4}, {'b': 30, 'h': 40})
exec(expr, {'a': 3, 'b': 4}, {'b': 30, 'h': 40}, {'b': 300, 'h': 400})
print (b)
func()
报错如下:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-95-c60febbcd644> in <module>
15 print (b)
16
---> 17 func()
<ipython-input-95-c60febbcd644> in func()
12 exec(expr, {'a': 3, 'b': 4})
13 exec(expr, {'a': 3, 'b': 4}, {'b': 30, 'h': 40})
---> 14 exec(expr, {'a': 3, 'b': 4}, {'b': 30, 'h': 40}, {'b': 300, 'h': 400})
15 print (b)
16
TypeError: exec expected at most 3 arguments, got 4
以上就是exec的用法了,如果还有别的特殊之处,欢迎大家随时交流~