1. 程式人生 > >筆記-python-built-in functions-eval,exec,compile

筆記-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