Python進階技巧彙總02
總結自原創: Leoxin 菜鳥學Python
原文地址:強烈推薦|麻煩剛關注2699名小夥伴一定要看,資訊量太大
1 函式
- 如何避開變數作用域的陷阱:
先思考一個例子,問最後X的值是多少?
x=99
def func1():
global x
x=88
def func2():
global x
x=77
首先,全域性變數是位於模組檔案內部的頂層的變數名,如何是在函式內被改變的話,一定要用global關鍵字,全域性變數名在函式內部不經過宣告也可以被引用。其次,函式內的變數解析原則(LEGB法則),當在函式中使用沒有宣告過的變數時,python的搜尋順序是:
- 先是在函式內部的本地作用域(L)
- 然後是在上一層的函式的本地作用域(E)
- 然後是全域性作用域(G)
- 最後是內建作用域(B)
最後,上述X的值不是88也不是77,而是都有可能,因為不確定先呼叫哪個函式,變數的值取決於函式呼叫的順序,而函式自身是任意順序進行排列的,所以88,77都有可能,看哪個函式最後呼叫.
2 檔案處理基礎
- Python檔案常用的場景和用法:
具體應用場景包括:檔案的處理、檔案路徑的處理、建立並訪問目錄、判斷是否為檔案或者目錄
(1)檔案處理
假設在當前目錄下有一個'abc.txt',下面所有操作都要import os
- 重新命名檔案
os.rename('abc.txt','a123.txt')
>>'abc.txt'變成了'a123.txt'
- 刪除檔案
os.remove('a123.txt')
# 但是在刪除之前,最好先判斷'a123.txt'是否存在,改成:
if os.path.exists('a123.txt'):
os.remove('a123.txt')
(2)檔案路徑的處理
假設有一個檔案路徑path='/users/Python/Data/info.txt'
- 獲得路徑
print os.path.dirname(path) >>>/users/Python/Data
- 分割檔名
print(os.path.basename(path))
>>>info.txt
- 分割檔案的字尾
print(os.path.split(path))
>>>('/users/Python/Data', 'info.txt')
(3)建立並訪問目錄
假設建立一個test01,test02目錄
- 建立目錄
os.mkdir('test01') # 在當前目錄下建立一個test01目錄
os.mkdir('test02') # 在當前目錄下建立一個test02目錄
# 改進,最好在建立之間先判斷目錄是否存在,否則會報錯
if not os.path.exists('test01'):
os.mkdir('test01')
if not os.path.exists('test02'):
os.mkdir('test02')
- 列出當前目錄下的所有檔案和資料夾
|---test01--------
|---test02--------
|---demo_file.py--
print(os.listdir('.'))
>>>['demo_file.py', 'test01', 'test02']
print(list(os.walk('.'))) == # walk()會生成當前目錄下的所有檔案和目錄==
>>>[('.', ['test01', 'test02'], ['demo_file.py']), ('.\\test01', [], []), ('.\\test02', [], [])]
- 返回當前的目錄
print(os.getcwd())
>>>C:\Users\xx\Python\Test
- 刪除目錄
os.rmdir('test02') # 如果裡面還有其他檔案和目錄,要一併刪除,可以用高階模組shutil來處理
(4)判斷是否為檔案或者目錄
假設我們有和(3)一樣的目錄結構
- 判斷是否為檔案
print(os.path.isfile('test01'))
>>>False
print(os.path.isfile('demo_file.py'))
>>True
- 判斷是否為目錄
print(os.path.isdir('test01'))
>>True
- 判斷檔案或者目錄是否存在
print(os.path.exists('demo_file.py'))
>>True
print(os.path.exists('test01'))
>>True
3 檔案處理進階技巧
- 如何對多個檔案中的內容替換,假設在當前目錄下有2個檔案test01.txt,test02.txt我們需要把裡面的Java全部替換為Python,一次搞定怎麼做呢?
|--test01.txt---
Hi All,
What Is Java?
What Is Programming?
|--test02.txt---
Hi All,
Why do people use Java?
It’s an important tool to learn
# Python標準庫裡面的fileinput模組允許你迴圈一個或多個文字檔案的內容,非常實用
import fileinput
import glob
# 利用glob模組過濾出當前目錄下所有的txt檔案
# inplace=1 標準輸出,比如print會被重定向到開啟檔案
# 把每一行去掉回車,然後把java替換為Python
for line in fileinput.input(glob.glob('*.txt'),inplace=1):
print(line.strip().replace('Java','Python'))
fileinput.close() # 關閉檔案控制代碼
- 如何列出全目錄結構?(用python內建模組的os.walk()函式)
假如我們有這樣的一個目錄結構為'C:\myPython',結構如下:
|---demo---
|--demo_01.exe
|--demo_02.msi
|--other
|--info.docc
|---log-----
|--1110_log.txt
|--1111_log.txt
|--1112_log.txt
|---pic-----
|--0127_1.jpg
|--0127_2.jpg
|--0127_3.jpg
import os
path=r'C:\myPython'
for folderName,subfolders,filenames in os.walk(path):
print 'The current folder is :'+folderName
for subfolder in subfolders: # 列出子目錄
print ('Subfolder of '+folderName+': '+subfolder)
for file_name in filenames: # 列出檔案
print ('File insdie '+folderName+': '+file_name)
>>>
The current folder is :C:\myPython
Subfolder of C:\myPython: demo
Subfolder of C:\myPython: log
Subfolder of C:\myPython: pic
The current folder is :C:\myPython\demo
Subfolder of C:\myPython\demo: other
File insdie C:\myPython\demo: demo_01.exe
File insdie C:\myPython\demo: demo_02.msi
The current folder is :C:\myPython\demo\other
File insdie C:\myPython\demo\other: info.docx
The current folder is :C:\myPython\log
File insdie C:\myPython\log: 1110_log.txt
File insdie C:\myPython\log: 1111_log.txt
File insdie C:\myPython\log: 1112_log.txt
The current folder is :C:\myPython\pic
File insdie C:\myPython\pic: 0127_1.jpg
File insdie C:\myPython\pic: 0127_2.jpg
File insdie C:\myPython\pic: 0127_3.jpg
- 如何把多個檔案copy到另外一個目錄下?(用高階檔案模組shutil搞定)
假如我們當前目錄下有這樣一個檔案結構,我們想把test01.txt和text02.txt備份到backup下,怎麼辦:
|---backup---
|--abc.txt
|---test01.txt---
|---test02.txt---
# 列出所有的檔案
# 過濾出txt檔案
# copy到backup下
import shutil,os
for file in os.listdir('.'):
if os.path.splitext(file)[1]=='.txt':
shutil.copy(file,os.path.join('backup',file))
# 建立了backup2目錄,然後把backup下的檔案全部都copy過來
shutil.copytree('backup', 'backup2')
- 刪除目錄以及所有子目錄的檔案
# 若這個目錄下面有檔案,或者不為空,直接用os.rmdir('backup2'),會報錯,告訴你:The directory is not empty: 'backup2'
# 用這個
shutil.rmtree('backup2')