python中關于eval函數的使用及說明

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-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 可用字節

總結

以上為個人經驗,希望能給大家一個參考

繼續閱讀
我的微信
微信掃一掃
weinxin
我的微信
惠生活福利社
微信掃一掃
weinxin
我的公眾號
 
  • 本文由 四五設計網小助手 發表于 2024年4月2日10:12:54
  • 轉載請務必保留本文鏈接:http://www.wasochina.com/44516.html

發表評論

匿名網友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

拖動滑塊以完成驗證