python函數——eval()、os.path、shutil 、request.files.get、re.findall、replace

一、eval()

eval() 函數用來執行一個字符串表達式,並返回表達式的值。

eval(expression[, globals[, locals]])

參數
os.path

expression – 表達式。
globals – 變量作用域,全局命名空間,如果被提供,則必須是一個字典對象。
locals --變量作用域,局部命名空間,如果被提供,可以是任何映射對象。

字符串與list、tuple、dict的轉化

a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
b = eval(a)
b
Out[3]: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
type(b)
Out[4]: list
a = "{1: 'a', 2: 'b'}"
b = eval(a)
b
Out[7]: {1: 'a', 2: 'b'}
type(b)
Out[8]: dict
a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
b = eval(a)
b
Out[11]: ([1, 2], [3, 4], [5, 6], [7, 8], (9, 0))

給個字符串給eval,eval給你一個表達式返回值

  1. 傳遞globals參數值爲{“age”:1822}
eval("{'name':'linux','age':age}",{"age":1822})

輸出結果:{‘name’: ‘linux’, ‘age’: 1822}

再加上locals變量

age=18
eval("{'name':'linux','age':age}",{"age":1822},locals())

輸出 {'age': 18, 'name': 'linux'}
根據上面兩個例子可以看到當locals參數爲空,globals參數不爲空時,查找globals參數中是否存在變量,並計算。

當兩個參數都不爲空時,先查找locals參數,再查找globals參數,locals參數中同名變量會覆蓋globals中的變量。

二、危險之處

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

eval("__import__('os').system('ls /Users/chunming.liu/Downloads/')")

那麼eval()之後,你會發現,當前文件夾文件都會展如今用戶前面。這句其實相當於執行了

os.system('ls /Users/chunming.liu/Downloads/')

那麼繼續輸入:

eval("__import__('os').system('cat /Users/chunming.liu/Downloads/tls_asimov_cert.pem')")

代碼都給人看了。
再來一條刪除命令,文件消失。比如

eval("__import__('os').system('rm /Users/chunming.liu/Downloads/車輛轉發測試.png')")

三、 os.path.join

連接兩個或更多的路徑名組件

1.如果各組件名首字母不包含’/’,則函數會自動加上

2.第一個以”/”開頭的參數開始拼接,之前的參數全部丟棄,當有多個時,從最後一個開始

3.如果最後一個組件爲空,則生成的路徑以一個’/’分隔符結尾

print(“2:”,os.path.join(’/aaaa’,’/bbbb’,’/ccccc.txt’)) #不良寫法習慣

2: /ccccc.txt

print(“22:”,os.path.join(’/aaaa/’,‘bbbb/’,‘ccccc.txt’)) #通常可以這樣寫

22: aaaa/bbb/ccccc.txt

print(“1:”,os.path.join(‘aaaa’,’/bbbb’,‘ccccc.txt’))

#以字符串中含有 / 的第一個開始拼接:

1: /bbbb/ccccc.txt

os.path.exists()
os.path模塊主要用於文件的屬性獲取,exists是“存在”的意思,所以顧名思義,os.path.exists()就是判斷括號裏的文件是否存在的意思,括號內的可以是文件路徑。
如果不存在,返回的則是FALSE
舉例如下:

 Finalpath = os.path.join(CertificateRootPath,'c6',NfvoIp)
 if not os.path.exists(Finalpath):
 		os.mkdir(Finalpath)

之前網上查找os.path.isdir()和os.path.isfile()的使用;發現很多是錯誤的,主要原因是,傳入的參數不是絕對路徑。

os.listdir()方法,此方法返回一個列表,其中包含有指定路徑下的目錄和文件的名稱

import os
dirct = '/home/vnfm/vnfm-develop/'
for i in os.listdir(dirct):
    print(i)


['vnfm', 'vnfm-env']

os.path.isdir()和os.path.isfile()需要傳入的參數是絕對路徑,但是os.listdir()返回的只是一個某個路徑下的文件和列表的名稱.

常見錯誤:直接使用os.listdir()的返回值當做os.path.isdir()和os.path.isfile()的入參

正確用法:需要先使用python路徑拼接os.path.join()函數,將os.listdir()返回的名稱拼接成文件或目錄的絕對路徑再傳入os.path.isdir()和os.path.isfile().

os.path.join()用法:

import os
dirct = '/home/vnfm/vnfm-develop/'
for i in os.listdir(dirct):
    fulldirct = os.path.join(dirct,i)
    print(fulldirct)
    
    
/home/vnfm/vnfm-develop/vnfm
/home/vnfm/vnfm-develop/vnfm-env

os.path.isdir()用於判斷某一對象(需提供絕對路徑)是否爲目錄

import os
dirct = '/home/vnfm/vnfm-develop/vnfm/'
for i in os.listdir(dirct):
    fulldirct = os.path.join(dirct, i)
    if os.path.isdir(fulldirct): 
        print(i)	
 
        
.git
documents
policy
vnfm
vnfd

os.path.isfile()用於判斷某一對象(需提供絕對路徑)是否爲文件

import os
dirct = '/home/vnfm/vnfm-develop/vnfm/'
for i in os.listdir(dirct):
    fulldirct = os.path.join(dirct, i)
    if os.path.isfile(fulldirct): 
        print(i)
    
entrypoint.sh
upgrade_vnfm.sh      
如果該目錄下有文件,打印出文件名        

os.path.abspath(path) 返回絕對路徑

shutil.rmtree() 表示遞歸刪除文件夾下的所有子文件夾和子文件
因此如果想刪除E盤下某個文件夾,可以用

shutil.rmtree('E:\\myPython\\image-filter\\test', ignore_errors=True)

這樣 test 文件夾內的所有文件(包括 test 本身)都會被刪除,並且忽略錯誤。

四、 request.files.get

file_obj = request.files.get(‘file’) 的方式獲取文件對象
返回值 file_obj 是一個文件對象,但是我們平常在使用時通常是在open() 函數中指定打開方式的,可是這裏並不知道這個文件對象中的數據是何種編碼方式,因此就會出現中文亂碼的問題

解決方法:
先從文件對象中將內容讀出,然後再按照我們想要的格式解碼(通常 utf-8)。

 file_obj = request.files.get('file')
 file_content = file_obj.read()
 file_content = file_content.decode("utf-8")
 print('答案內容爲:', file_content)

request中的files屬性,,,記錄請求上傳的文件

已上傳的文件存儲在內存或是文件系統中一個臨時的位置。你可以通過請求對象的 files 屬性訪問它們。

每個上傳的文件都會存儲在這個字典裏。它表現近乎爲一個標準的 Python file 對象,

但它還有一個 save() 方法,這個方法允許你把文件保存到服務器的文件系統上

例如:

if request.files.get('ca_cert'):
     request_data = request.files.get('ca_cert')
     request_data.save(Finalpath+'/ca.cert')

例子2:

from flask import Flask, request
 
app = Flask(__name__)
 
'''因爲是文件,所以只能是POST方式'''
@app.route("/upload", methods=["POST"])
def upload():
    """接受前端傳送來的文件"""
    file_obj = request.files.get("pic")
    if file_obj is None:
        # 表示沒有發送文件
        return "未上傳文件"
 
    '''
        將文件保存到本地(即當前目錄)
        直接使用上傳的文件對象保存
    '''
    file_obj.save('pic.jpg')  # 和前端上傳的文件類型要相同
    return "上傳成功"
 
    # 將文件保存到本地(即當前目錄) 普通的保存方法
    # with open("./pic.jpg",'wb') as f:
    #     data = file_obj.read()
    #     f.write(data)
    #     return "上傳成功"
 
if __name__ == '__main__':
    app.run(debug=True)

request方法擴展請點擊這個鏈接

關於make_response響應、redirect跳轉,請點擊Flask中request請求、make_response響應、redirect跳轉

五、re.findall(pattern, text)(關鍵詞:python/正則表達式/re)

findall(pattern, text)函數會返回輸入中與模式匹配而不重疊的所有子串

import re
text = 'abbaaabbbbaaaaa'
pattern = 'ab'

for match in re.findall(pattern, text):
        print 'Found "%s"' % match

輸出:

Found “ab”
Found “ab”

import re
kk = re.compile(r'\d+')
kk.findall('one1two2three3four4')
#[1,2,3,4]
 
#注意此處findall()的用法,可傳兩個參數;
kk = re.compile(r'\d+')
re.findall(kk,"one123")
#[1,2,3]

從compile()函數的定義中,可以看出返回的是一個匹配對象,它單獨使用就沒有任何意義,需要和findall(), search(), match()搭配使用。
compile()與findall()一起使用,返回一個列表。
compile()與match()一起使用,可返回一個class、str、tuple。但是一定需要注意match(),從位置0開始匹配,匹配不到會返回None,返回None的時候就沒有span/group屬性了,並且與group使用,返回一個單詞‘Hello’後匹配就會結束。
compile()與search()搭配使用, 返回的類型與match()差不多, 但是不同的是search(), 可以不從位置0開始匹配。但是匹配一個單詞之後,匹配和match()一樣,匹配就會結束。

\s表示空格
\w表示任何字符,包括字母數字下劃線
_就表示下劃線
\s – 匹配任何不可見字符,包括空格、製表符、換頁符等等
\S – 匹配任何可見字符 通常[/s/S] – 可匹配任意字符
[\s\S]*? – 匹配懶惰模式的任意字符

詳情: 查看相關區別

正則表達式有括號時 可能遇到得坑 ,請點擊Python 正則re模塊之findall()詳解

六、替換函數replace()

Python replace() 方法把字符串中的 old(舊字符串) 替換成 new(新字符串),如果指定第三個參數max,則替換不超過 max 次。

str.replace(old, new[, max])

返回字符串中的 old(舊字符串) 替換成 new(新字符串)後生成的新字符串,如果指定第三個參數max,則替換不超過 max 次

str = "this is string example....wow!!! this is really string";
print str.replace("is", "was");
print str.replace("is", "was", 3);

if '[' in VimIp:
     VimIp = VimIp.replace('[','').replace(']','') 

七、

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章