eval是Python的一個內置函數,功能十分強大,這個函數的作用是,返回傳入字符串的表達式的結果。
就是說:將字符串當成有效的表達式 來求值 并 返回計算結果。文章源自四五設計網-http://www.wasochina.com/44516.html
eval函數就是實現list、dict、tuple與str之間的轉化,同樣str函數把list,dict,tuple轉為為字符串文章源自四五設計網-http://www.wasochina.com/44516.html
1.eval的語法
1 | eval (expression[, globals [, locals ]]) |
expression?
: 表達式。globals?
: (可選參數)變量作用域,全局命名空間,如果被提供,則必須是一個字典對象。locals?
: (可選參數)變量作用域,局部命名空間,如果被提供,可以是任何映射對象。
既然eval有兩個可選參數是命名空間,那么先搞清楚啥是命名空間吧?文章源自四五設計網-http://www.wasochina.com/44516.html
2.命名空間
定義
名稱到對象的映射。python是用命名空間來記錄變量的軌跡的,命名空間是一個dictionary,鍵是變量名,值是變量值。各個命名空間是獨立沒有關系的,一個命名空間中不能有重名,但是不同的命名空間可以重名而沒有任何影響。文章源自四五設計網-http://www.wasochina.com/44516.html
分類
python程序執行期間會有2個或3個活動的命名空間(函數調用時有3個,函數調用結束后2個)。按照變量定義的位置,可以劃分為以下3類:文章源自四五設計網-http://www.wasochina.com/44516.html
Local
,局部命名空間,每個函數所擁有的命名空間,記錄了函數中定義的所有變量,包括函數的入參、內部定義的局部變量。Global
,全局命名空間,每個模塊加載執行時創建的,記錄了模塊中定義的變量,包括模塊中定義的函數、類、其他導入的模塊、模塊級的變量與常量。Built-in
,python自帶的內建命名空間,任何模塊均可以訪問,放著內置的函數和異常。
生命周期
Local
(局部命名空間)在函數被調用時才被創建,但函數返回結果或拋出異常時被刪除。(每一個遞歸函數都擁有自己的命名空間)。Global
(全局命名空間)在模塊被加載時創建,通常一直保留直到python解釋器退出。Built-in
(內建命名空間)在python解釋器啟動時創建,一直保留直到解釋器退出。
各命名空間創建順序:文章源自四五設計網-http://www.wasochina.com/44516.html
python解釋器啟動 ->創建內建命名空間 -> 加載模塊 -> 創建全局命名空間 ->函數被調用 ->創建局部命名空間文章源自四五設計網-http://www.wasochina.com/44516.html
各命名空間銷毀順序:文章源自四五設計網-http://www.wasochina.com/44516.html
函數調用結束 -> 銷毀函數對應的局部命名空間 -> python虛擬機(解釋器)退出 ->銷毀全局命名空間 ->銷毀內建命名空間文章源自四五設計網-http://www.wasochina.com/44516.html
python解釋器加載階段會創建出內建命名空間、模塊的全局命名空間,局部命名空間是在運行階段函數被調用時動態創建出來的,函數調用結束動態的銷毀的。文章源自四五設計網-http://www.wasochina.com/44516.html
python的全局命名空間存儲在一個叫globals()的dict對象中;局部命名空間存儲在一個叫locals()的dict對象中。
可以用print (locals())來查看該函數體內的所有變量名和變量值。
1 2 3 4 5 6 | print ( locals ()) ? #打印顯示所有的局部變量 ''' { '__name__' : '__main__' , '__doc__' : None , '__package__' : None , '__loader__' : <_frozen_importlib_external.SourceFileLoader object at 0x000001B22E13B128 >, '__spec__' : None , '__annotations__' : {}, '__builtins__' : <module 'builtins' (built - in )>, '__file__' : 'D:/pythoyworkspace/file_demo/Class_Demo/pachong/urllib_Request1.py' , '__cached__' : None , 's' : '1+2+3*5-2' , 'x' : 1 , 'age' : 18 } Process finished with exit code 0 |
3.參數查找
當后兩個參數都為空時,很好理解,就是一個string類型的算術表達式,計算出結果即可。等價于eval(expression)。
當locals參數為空,globals參數不為空時,先查找globals參數中是否存在變量,并計算。
當兩個參數都不為空時,先查找locals參數,再查找globals參數。
4.eval的使用演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #1.eval無參實現字符串轉化 s = '1+2+3*5-2' print ( eval (s)) ? #16 #2.字符串中有變量也可以 x = 1 print ( eval ( 'x+2' )) ? #3 #3.字符串轉字典 print ( eval ( "{'name':'linux','age':18}" )) #輸出結果:{'name':'linux','age':18} #4.eval傳遞全局變量參數,注意字典里的:age中的age沒有帶引號,說明它是個變量,而不是字符串。 #這里兩個參數都是全局的 print ( eval ( "{'name':'linux','age':age}" ,{ "age" : 1822 })) #輸出結果:{'name': 'linux', 'age': 1822} print ( eval ( "{'name':'linux','age':age}" ,{ "age" : 1822 },{ "age" : 1823 })) #輸出結果:{'name': 'linux', 'age': 1823} #eval傳遞本地變量,既有global和local時,變量值先從local中查找。 age = 18 print ( eval ( "{'name':'linux','age':age}" ,{ "age" : 1822 }, locals ())) #輸出結果:{'name': 'linux', 'age': 18} print ( "-----------------" ) print ( eval ( "{'name':'linux','age':age}" )) |
5.eval的使用與風險
python3中input將接受的結果存為字符串,一般來說,可以使用eval實現表達式的還原,并且實現表達式的計算
比如下面使用eval直接完成了表達式的還原與計算:
1 2 3 4 5 | >>> s = input ( "輸入一個表達式" ) 輸入一個表達式: 1 + 3 + 4 + 4 * 3 >>> print ( eval (s)) 20 >>> |
eval雖然方便,但是要注意安全性,可以將字符串轉成表達式并執行,就可以利用執行系統命令,刪除文件等操作。
比如用戶惡意輸入就會獲得當前目錄文件
>>>eval("__import__('os').system('dir')")
驅動器 C 中的卷是 OS
卷的序列號是 B234-8A38C:\Users\Robot_TENG 的目錄
2019-07-01 ?09:11 ? ?<DIR> ? ? ? ? ?.
2019-07-01 ?09:11 ? ?<DIR> ? ? ? ? ?..
2017-11-23 ?16:15 ? ?<DIR> ? ? ? ? ?.android
2018-12-23 ?00:02 ? ?<DIR> ? ? ? ? ?.conda
2018-12-06 ?19:08 ? ? ? ? ? ? ? ?20 .dbshell
2017-12-01 ?19:28 ? ?<DIR> ? ? ? ? ?.eclipse
2018-01-22 ?22:46 ? ?<DIR> ? ? ? ? ?.idea-build
2017-12-31 ?14:49 ? ?<DIR> ? ? ? ? ?.IdeaIC2017.1
2018-01-22 ?21:21 ? ?<DIR> ? ? ? ? ?.IdeaIC2017.2
2019-07-01 ?09:11 ? ?<DIR> ? ? ? ? ?.ipynb_checkpoints
2018-12-19 ?20:04 ? ?<DIR> ? ? ? ? ?.ipython
2019-07-01 ?09:30 ? ?<DIR> ? ? ? ? ?.jupyter
2017-12-01 ?16:11 ? ?<DIR> ? ? ? ? ?.m2
2017-12-31 ?23:14 ? ? ? ? ? ? ? ? 0 .mongorc.js
2019-02-03 ?22:52 ? ?<DIR> ? ? ? ? ?.p2
2018-07-16 ?22:04 ? ?<DIR> ? ? ? ? ?.PyCharm2016.1
2018-12-06 ?19:49 ? ?<DIR> ? ? ? ? ?.rdm
2018-01-22 ?22:09 ? ? ? ? ? ? ? 580 .scala_history
2018-12-06 ?19:19 ? ?<DIR> ? ? ? ? ?.vscode
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?3D Objects
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?Contacts
2019-07-01 ?16:21 ? ?<DIR> ? ? ? ? ?Desktop
2019-06-28 ?16:34 ? ?<DIR> ? ? ? ? ?Documents
2019-06-28 ?10:26 ? ?<DIR> ? ? ? ? ?Downloads
2018-09-11 ?22:24 ? ?<DIR> ? ? ? ? ?Evernote
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?Favorites
2018-08-02 ?23:58 ? ?<DIR> ? ? ? ? ?HBuilder
2018-08-03 ?00:00 ? ?<DIR> ? ? ? ? ?HBuilder settings
2018-08-03 ?00:02 ? ?<DIR> ? ? ? ? ?HBuilderProjects
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?Links
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?Music
2018-03-18 ?00:22 ? ?<DIR> ? ? ? ? ?Oracle
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?Pictures
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?Saved Games
2019-06-21 ?16:37 ? ?<DIR> ? ? ? ? ?Searches
2018-12-23 ?00:47 ? ? ? ? ? ? ? 690 Untitled.ipynb
2019-07-01 ?09:11 ? ? ? ? ? ? ? ?72 Untitled1.ipynb
2019-06-30 ?18:43 ? ?<DIR> ? ? ? ? ?Videos
2019-01-13 ?18:20 ? ?<DIR> ? ? ? ? ?Yinxiang Biji
5 個文件 ? ? ? ? ?1,362 字節
34 個目錄 72,365,862,912 可用字節
總結
以上為個人經驗,希望能給大家一個參考


評論