python中的eval函數的使用詳解

     eval是Python的一個內置函數,功能十分強大,這個函數的作用是,返回傳入字符串的表達式的結果。就是說:將字符串當成有效的表達式 來求值 並 返回計算結果。

    eval函數就是實現list、dict、tuple與str之間的轉化,同樣str函數把list,dict,tuple轉爲爲字符串

1.eval的語法

eval(expression[, globals[, locals]])
expression : 表達式。
globals : (可選參數)變量作用域,全局命名空間,如果被提供,則必須是一個字典對象。
locals : (可選參數)變量作用域,局部命名空間,如果被提供,可以是任何映射對象。

既然eval有兩個可選參數是命名空間,那麼先搞清楚啥是命名空間吧?

2.命名空間

【定義】

    名稱到對象的映射。python是用命名空間來記錄變量的軌跡的,命名空間是一個dictionary,鍵是變量名,值是變量值。各個命名空間是獨立沒有關係的,一個命名空間中不能有重名,但是不同的命名空間可以重名而沒有任何影響。

【分類】

    python程序執行期間會有2個或3個活動的命名空間(函數調用時有3個,函數調用結束後2個)。按照變量定義的位置,可以劃分爲以下3類:

    Local,局部命名空間,每個函數所擁有的命名空間,記錄了函數中定義的所有變量,包括函數的入參、內部定義的局部變量。

    Global,全局命名空間,每個模塊加載執行時創建的,記錄了模塊中定義的變量,包括模塊中定義的函數、類、其他導入的模塊、模塊級的變量與常量。

    Built-in,python自帶的內建命名空間,任何模塊均可以訪問,放着內置的函數和異常。

【生命週期】

    Local(局部命名空間)在函數被調用時才被創建,但函數返回結果或拋出異常時被刪除。(每一個遞歸函數都擁有自己的命名空間)。

    Global(全局命名空間)在模塊被加載時創建,通常一直保留直到python解釋器退出。

    Built-in(內建命名空間)在python解釋器啓動時創建,一直保留直到解釋器退出。

    各命名空間創建順序:python解釋器啓動 ->創建內建命名空間 -> 加載模塊 -> 創建全局命名空間 ->函數被調用 ->創建局部命名空間

    各命名空間銷燬順序:函數調用結束 -> 銷燬函數對應的局部命名空間 -> python虛擬機(解釋器)退出 ->銷燬全局命名空間 ->銷燬內建命名空間

    python解釋器加載階段會創建出內建命名空間、模塊的全局命名空間,局部命名空間是在運行階段函數被調用時動態創建出來的,函數調用結束動態的銷燬的。

   python的全局命名空間存儲在一個叫globals()的dict對象中;局部命名空間存儲在一個叫locals()的dict對象中。可以用print (locals())來查看該函數體內的所有變量名和變量值。

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.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直接完成了表達式的還原與計算:

>>> s = input("輸入一個表達式")
輸入一個表達式:1+3+4+4*3
>>> print(eval(s))
20
>>>

eval雖然方便,但是要注意安全性,可以將字符串轉成表達式並執行,就可以利用執行系統命令,刪除文件等操作。,比如用戶惡意輸入就會獲得當前目錄文件

>>>eval("__import__('os').system('dir')")
 驅動器 C 中的卷是 OS
 卷的序列號是 B234-8A38

 C:\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 可用字節
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章