Python 中的可執行對象 eval,exec 和 compile與其在深度學習訓練中的應用實例

Python 中的可執行對象 eval,exec 和 compile 與其在深度學習訓練中的應用實例

eval

計算指定表達式的值。也就是說它要執行的python代碼只能是單個表達式(注意eval不支持任何形式的賦值操作),而不能是復雜的代碼邏輯。

eval(source, globals=None, locals=None, /)

obj可以是字符串對象或者已經由compile編譯過的代碼對象。globals和locals是可選的,分別代表了全局和局部名稱空間中的對象,其中globals必須是字典,而locals是任意的映射對象。

參數說明:

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   #局部變量ya = 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

注意eval不能用于變量的賦值,例如:

eval('x = 3')
print(x)

輸出:

Traceback (most recent call last):File "111111.py", line 1, in <module>eval('x = 3')File "<string>", line 1x = 3^
SyntaxError: invalid syntax

exec

動態執行python代碼。也就是說exec可以執行復雜的python代碼,而不像eval函數那樣只能計算一個表達式的值。

exec(source, globals=None, locals=None, /)

source:必選參數,表示需要被指定的python代碼。它必須是字符串或code對象。如果source是一個字符串,該字符串會先被解析為一組python語句,然后執行。如果source是一個code對象,那么它只是被簡單的執行。

返回值:

exec函數的返回值永遠為None。

eval()函數和exec()函數的區別:

eval()函數只能計算單個表達式的值,而exec()函數可以動態運行代碼段。

eval()函數可以有返回值,而exec()函數返回值永遠為None。

例:

我們把eval中的例子拿過來執行

x = 10
def func():y = 20a = exec("x+y")print("a:",a)b = exec("x+y",{"x":1,"y":2})print("b:",b)c = exec("x+y",{"x":1,"y":2},{"y":3,"z":4})print("c:",c)d = exec("print(x,y)")print("d:",d)
func()

輸出:

#exec不會有任何返回值
a: None   
b: None
c: None
10 20
d: None

例:

x = 10
expr = """
z = 30
sum = x + y + z   #一大包代碼
print(sum)
"""
def func():y = 20exec(expr)   10+20+30exec(expr,{'x':1,'y':2}) 30+1+2exec(expr,{'x':1,'y':2},{'y':3,'z':4}) #30+1+3,x是定義全局變量1,y是局部變量func()

輸出:

60
33
34

并且exec可用于賦值,例如:

exec('x = 3')
print(x)

輸出:

3

complie

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)

參數說明

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

在深度學習訓練中的應用實例

首先介紹一個比較常用的記錄指標和損失的util。

class AverageMeter(object):'''Computes and stores the average and current value'''def __init__(self):self.reset()def reset(self):self.val = 0self.avg = 0self.sum = 0self.count = 0def update(self, val, n=1):self.val = valself.sum += val * nself.count += nself.avg = self.sum / self.count

使用這個AverageMeter類,在每個step內update以下要記錄的指標或者損失值,在每個epoch最后輸出其avg到tensorboard即可。

配合上面介紹的可執行對象。


def epoch_forward(metrics_list):for metric in metrics_list:exec("{} = AverageMeter()".format(metric))	# 實例化一個對象,注意這里相當于是在賦值,要用exec,不能用evalfor data in loader:'''training loop'''for metric in metrics_list:					# 每個step更新記錄eval("{}.update(_{})".format(metric, metric))			# 這里在訓練時統一用下劃線加指標名命名每個step的值 如:_loss# 簡單表達式 eval,exec都可		metrics_res_list = []						# 每個epoch結束,返回記錄的指標值for metric in metrics_list:metrics_res_list.append(eval("{}.avg".format(metric)))return metrics_res_list			# 返回記錄的指標值def store_curve(writer, metrics_list, metrics_res_list, epoch):for i in range(len(metrics_list)):exec("writer.add_scalar('{}', {}, {})".format(metrics_list[i], metrics_res_list[i], epoch))		# 將記錄的指標值輸出到tensorboardif __name__ == "__main__":'''preparision for training (model, dataset, ...)'''writer = SummaryWriter("runs")for epoch in epochs:metrics_list = ['acc', 'loss']	# 給定要記錄的指標或損失列表metrics_res_list = epoch_forward(metrics_list)store_curve(writer, metrics_list, metrics_res_list, epoch)

主要想法就是在之前保存指標時要寫一大列相似的東西,覺得很繁瑣,就想找到一個比較優雅的解決辦法,以上這個自己設計的用可執行對象做的方法是比較不錯的,每次要記錄的指標有變動時只需在training loop里面計算好,然后改一下metrics_list即可。

注意在賦值時只能用exec。

留存問題

exec為什么不能在函數中用,只能在全局用。

前半部分介紹可執行對象參考博客:https://www.cnblogs.com/yangmingxianshen/p/7810496.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532866.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532866.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532866.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php寫簡單接口_php寫接口的日常

php寫接口的日常/*評論列表*/public function commentListW(){$base new Base();$info $base->getUserByToken();$shop_id $info[shop_id];$page $this->data[page]?:1;$pagesize $this->data[pagesize]?:C(ROLLPAGE);$search $this->data[search];$and &…

mmdetection 使用筆記 01: 安裝與簡單的推理demo

mmdetection 使用筆記 01: 安裝與簡單的推理demo mmdetection是來自商湯和港中文聯合實驗室openmmlab推出的目標檢測工具包&#xff0c;與其同系列的還有基礎視覺包mmcv&#xff0c;圖像分類mmclassification&#xff0c;還有mmaction&#xff0c;mmaction2等等。 今天第一次…

php無限評論回復_php實現無限級評論功能_后端開發

php去除數組的鍵名的方法_后端開發在php中可以使用“array_values()”函數去除數組的鍵名&#xff0c;該函數返回包含數組中所有的值的數組&#xff0c;其語法是“array_values(array)”&#xff0c;其參數“array”表示規定的數組&#xff0c;返回值是包含數組中所有的值的數組…

錯誤類型、混淆矩陣及目標檢測常用評價指標

目標檢測常用評價指標 本文主要參考陳愷大佬在B站商湯賬號的介紹mmdetection的視頻。 檢測結果的正確/錯誤類型 真陽性&#xff08;Ture Positive&#xff09;&#xff1a;算法檢測到了某類物體&#xff08;Positive&#xff09;&#xff0c;而實際圖中也確實有這個物體&…

php顯示json,PHP解決JSON中文顯示問題

PHP如何解決JSON中文顯示問題&#xff1f;本文主要介紹了PHP JSON格式的中文顯示問題解決方法&#xff0c;本文總結了3種解決中文顯示\u開頭字符問題的方法。希望對大家有所幫助。返回json數據中文顯示的問題解決方法一&#xff1a;<?php function Notice(){include ./incl…

使用yolov5訓練自己的目標檢測數據集

使用yolov5訓練自己的目標檢測數據集 yolov4出來后不久&#xff0c;又出現了yolov5&#xff0c;沒有論文。雖然作者沒有放上和yolov4的直接測試對比&#xff0c;但在COCO數據集的測試效果還是很可觀的。很多人考慮到YOLOv5的創新性不足&#xff0c;對算法是否能夠進化&#xf…

php的integer,PHP整型 integer

整數是一個沒有小數的數字。整數規則:整數必須至少有一個數字 (0-9)整數不能包含逗號或空格整數是沒有小數點的整數可以是正數或負數整型可以用三種格式來指定&#xff1a;十進制&#xff0c; 十六進制( 以 0x 為前綴)或八進制(前綴為 0)。在以下實例中我們將測試不同的數字。 …

einops和einsum:直接操作張量的利器

einops和einsum&#xff1a;直接操作張量的利器 einops和einsum是Vision Transformer的代碼實現里出現的兩個操作tensor維度和指定tensor計算的神器&#xff0c;在卷積神經網絡里不多見&#xff0c;本文將介紹簡單介紹一下這兩樣工具&#xff0c;方便大家更好地理解Vision Tra…

php的filter input,php中filter_input函數用法分析

本文實例分析了php中filter_input函數用法。分享給大家供大家參考。具體分析如下&#xff1a;在 php5.2 中,內置了filter 模塊,用于變量的驗證和過濾,過濾變量等操作&#xff0c;這里我們看下如何直接過濾用戶輸入的內容.fliter 模塊對應的 filter_input 函數使用起來非常的簡單…

COCO 數據集格式及mmdetection中的轉換方法

COCO 數據集格式及mmdetection中的轉換方法 COCO格式 CV中的目標檢測任務不同于分類&#xff0c;其標簽的形式稍為復雜&#xff0c;有幾種常用檢測數據集格式&#xff0c;本文將簡要介紹最為常見的COCO數據集的格式。 完整的官方樣例可自行查閱&#xff0c;以下是幾項關鍵的…

php獲取h1,jQuery獲取h1-h6標題元素值方法實例

本文主要介紹了jQuery實現獲取h1-h6標題元素值的方法,涉及$(":header")選擇器操作h1-h6元素及事件響應相關技巧,需要的朋友可以參考下&#xff0c;希望能幫助到大家。1、問題背景&#xff1a;查找到h1-h6&#xff0c;并遍歷它們&#xff0c;打印出內容2、實現代碼&am…

在導入NVIDIA的apex庫時報錯 ImportError cannot import name ‘UnencryptedCookieSessionFactoryConfig‘ from

在導入NVIDIA的apex庫時報錯 ImportError: cannot import name ‘UnencryptedCookieSessionFactoryConfig’ from ‘pyramid.session’ (unknown location) 報錯 在使用NVIDIA的apex庫時報錯 ImportError: cannot import name ‘UnencryptedCookieSessionFactoryConfig’ fro…

php怎么取request,PHP-如何在Guzzle中獲取Request對象?

我需要使用Guzzle檢查數據庫中的很多項目.例如,項目數量為2000-5000.將其全部加載到單個數組中太多了,因此我想將其分成多個塊&#xff1a;SELECT * FROM items LIMIT100.當最后一個項目發送到Guzzle時,則請求下一個100個項目.在“已滿”處理程序中,我應該知道哪個項目得到了響…

[2021-CVPR] Jigsaw Clustering for Unsupervised Visual Representation Learning 論文簡析及關鍵代碼簡析

[2021-CVPR] Jigsaw Clustering for Unsupervised Visual Representation Learning 論文簡析及關鍵代碼簡析 論文&#xff1a;https://arxiv.org/abs/2104.00323 代碼&#xff1a;https://github.com/dvlab-research/JigsawClustering 總結 本文提出了一種單批次&#xff0…

java jps都卡死,java長時間運行后,jps失效

在部署完應用后&#xff0c;原本jps使用的好好的&#xff0c;能正確的查詢到自己正在運行的java程序。但&#xff0c;過了一段時間后&#xff0c;再使用jps來查看運行的應用時&#xff0c;自己運行的程序都看不到&#xff0c;但是自己也沒有關閉這些程序啊&#xff01;然而使用…

指針(*)、取地址()、解引用(*)與引用()

指針(*)、取地址(&)、解引用(*)與引用(&) C 提供了兩種指針運算符&#xff0c;一種是取地址運算符 &&#xff0c;一種是間接尋址運算符 *。 指針是一個包含了另一個變量地址的變量&#xff0c;您可以把一個包含了另一個變量地址的變量說成是"指向"另一…

matlab電類,985電氣研二,有發過考研經驗貼 電氣電力類的有

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓clc;clear;p[2.259;2.257;2.256;2.254;2.252;2.248;2.247;2.245;2.244;2.243;2.239;2.238;2.236;2.235;2.234;2.231;2.229;2.228;2.226;2.225;2.221;2.220;2.219;2.217;2.216;2.211;2.209;2.208;2.207;2.206;2.202;2.201;2.199;2.1…

matlab legend 分塊,matlab?legend?分塊!

matlab legend 分塊&#xff01;(2013-03-26 18:07:38)%%%壓差clc;clear all;figure(55);set (gcf,Position,[116 123 275 210],color,w);P[25 26 27 28 29 30 31 32 33 34 35];%理論q0.00006*pi*28*P*10^(6)*0.03^3/(12*0.028448*5);q1110.00006*pi*28*P*10^(6)*0.03^3/(12*0.…

利用opencv-python繪制多邊形框或(半透明)區域填充(可用于分割任務mask可視化)

利用opencv-python繪制多邊形框或&#xff08;半透明&#xff09;區域填充&#xff08;可用于分割任務mask可視化&#xff09; 本文主要就少opencv中兩個函數polylines和fillPoly分別用于繪制多邊形框或區域填充&#xff0c;并會會以常見用途分割任務mask&#xff08;還是筆者…

matlab與maple互聯,Matlab,Maple和Mathematica三款主流科學計算軟件的互操作

本文根據網上零散的信息以及這三款軟件自帶的說明文檔整理而成&#xff0c;為備忘而記錄。記錄了Matlab和Maple之間的相互調用&#xff0c;以及Matlab和Mathematica之間相互調用的安裝配置方法。為何需要互操作&#xff1f; 數值計算和圖形方面Matlab毫無疑問是最強的&a…