1. 程式人生 > >Python進階技巧彙總02

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')