筆記-python-built-in functions-eval,exec,compile
筆記-python-built-in functions-eval,exec,compile
1. python程式碼執行函式
有時需要動態改變程式碼,也就是說程式碼需要是字串格式,然後在按需要編譯,這時,需要一些執行程式碼的函式,js中的是eval(),python中也有類似內建函式。
1.1. eval函式
函式的作用:
計算指定表示式的值。也就是說它要執行的python程式碼只能是單個表示式(注意eval不支援任何形式的賦值操作),而不能是複雜的程式碼邏輯。
eval(source, globals=None, locals=None, /)
引數說明:
source:必選引數,可以是字串,也可以是一個任意的code(程式碼)物件例項(可以通過complie函式建立)。如果它是一個字串,它會被當作一個(使用globals和locals引數作為全域性和本地名稱空間的)python表示式進行分析和解釋。
globals:可選引數,表示全域性名稱空間(存放全域性變數),如果被提供,則必須是一個字典物件。
locals:可選引數,表示全域性名稱空間(存放區域性變數),如果被提供,可以是任何對映物件。如果引數被忽略,那麼它將會取與globals相同的值。
如果globals與locals都被忽略,那麼它們將取eval()函式被呼叫環境下的全域性名稱空間和區域性名稱空間。
返回值:
如果source是一個code物件,且建立該code物件時,complie函式的mode引數是‘exec’,那麼eval()函式的返回值是None;
否則,如果source是一個輸出語句,如print(),則eval()返回結果為None;
否則,source表示式的結果就是eval()函式的返回值
例項:
x = 10
def func():
y = 20 #區域性變數y
a = eval("x+y")
print("a:",a) #x沒有就呼叫全域性變數
b = eval("x+y",{"x":1,"y":2}) #定義區域性變數,優先呼叫
print("b:",b)
c = eval("x+y",{"x":1,"y":2},{"y":3,"z":4})
print("c:",c)
d = eval("print(x,y)")
print("d:",d) #對於變數d,因為print()函式不是一個計算表示式,因此沒有返回值
func()
輸出結果:
a: 30
b: 3
c: 4
10 20
d: None
1.2. exec函式
函式的作用:
動態執行python程式碼。也就是說exec可以執行復雜的python程式碼,而不像eval函式那樣只能計算一個表示式的值。
exec(source, globals=None, locals=None, /)
source:必選引數,表示需要被指定的python程式碼。它必須是字串或code物件。如果source是一個字串,該字串會先被解析為一組python語句,然後執行。如果source是一個code物件,那麼它只是被簡單的執行。
返回值:
exec函式的返回值永遠為None。
x = 10
expr = """
z = 30
sum = x + y + z #一大包程式碼
print(sum)
"""
def func():
y = 20
exec(expr) #10+20+30
exec(expr,{'x':1,'y':2}) #0+1+2
exec(expr,{'x':1,'y':2},{'y':3,'z':4}) #30+1+3,x是定義全域性變數1,y是區域性變數
func()
另外,在exec中是可以賦值的,基本等同於js的eval。
>>> c = 'b=78+45'
>>> exec(c)
>>> b
123
也可以定義函式:
>>> c = """def func(a):print(a)"""
>>> exec(c)
>>> func
<function func at 0x0000002D3656D6A8>
>>> func(5)
5
>>>
1.3. complie函式
compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
Compile the source into a code or AST object. Code objects can be executed by exec() or eval(). source can either be a normal string, a byte string, or an AST object. Refer to the ast module documentation for information on how to work with AST objects.
引數說明:
source:字串或AST物件,表示需要進行編譯的python程式碼
filename:指定需要編譯的程式碼檔案,如果不是檔案讀取程式碼則傳遞一些可辨認的值。
mode:用於標識必須當做那類代表來編譯;如果source是由一個程式碼語句序列組成,則指定mode=‘exec’,如果source由單個表示式組成,則指定mode=‘eval’;如果source是由一個單獨的互動式語句組成,則指定modo=‘single’。必須要制定,不然肯定會報錯。
例子:
s = """ #一大段程式碼
for x in range(10):
print(x, end='')
print()
"""
code_exec = compile(s, '<string>', 'exec') #必須要指定mode,指定錯了和不指定就會報錯。
code_eval = compile('10 + 20', '<string>', 'eval') #單個表示式
code_single = compile('name = input("Input Your Name: ")', '<string>', 'single') #互動式
a = exec(code_exec) 使用的exec,因此沒有返回值
b = eval(code_eval)
c = exec(code_single) 互動
d = eval(code_single)
print('a: ', a)
print('b: ', b)
print('c: ', c)
print('name: ', name)
print('d: ', d)
print('name; ', name)
執行結果:
0123456789 #有print就會列印
Input Your Name: kebi
Input Your Name: kebi
a: None
b: 30
c: None
name: kebi
d: None
name; kebi