1. 程式人生 > >Python 第三天學習整理①

Python 第三天學習整理①

今天學習的內容包括以下幾個方面:1.字元編碼 2.檔案操作 3.函式

1.字元編碼

關於字元編碼,關注以下幾個點

1.1 什麼是字元編碼

字元編碼:字元轉化為數字的過程所遵循的標準

字元編碼包括:unicode,gbk,utf-8等。

字元編碼的核心原則:保持存取一致

1.2 字元編碼的發展史

階段一:現代計算機起源於美國,最早誕生也是基於英文考慮的ASCII

  ASCII:一個Bytes代表一個字元(英文字元/鍵盤上的所有其他字元),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字元

    ASCII最初只用了後七位,127個數字,已經完全能夠代表鍵盤上所有的字元了(英文字元/鍵盤的所有其他字元)

    後來為了將拉丁文也編碼進了ASCII表,將最高位也佔用了

 

階段二:為了滿足中文,中國人定製了GBK

  GBK:2Bytes代表一個字元

 

  為了滿足其他國家,各個國家紛紛定製了自己的編碼

  日本把日文編到Shift_JIS裡,韓國把韓文編到Euc-kr

 

階段三:各國有各國的標準,就會不可避免地出現衝突,結果就是,在多語言混合的文字中,顯示出來會有亂碼。

於是產生了unicode, 統一用2Bytes代表一個字元, 2**16-1=65535,可代表6萬多個字元,因而相容萬國語言

但對於通篇都是英文的文字來說,這種編碼方式無疑是多了一倍的儲存空間(二進位制最終都是以電或者磁的方式儲存到儲存介質中的)

於是產生了UTF-8,對英文字元只用1Bytes表示,對中文字元用3Bytes

 

需要強調的一點是:

unicode:簡單粗暴,所有字元都是2Bytes,優點是字元->數字的轉換速度快,缺點是佔用空間大

utf-8:精準,對不同的字元用不同的長度表示,優點是節省空間,缺點是:字元->數字的轉換速度慢,因為每次都需要計算出字元需要多長的Bytes才能夠準確表示

      

  1. 記憶體中使用的編碼是unicode,用空間換時間(程式都需要載入到記憶體才能執行,因而記憶體應該是儘可能的保證快)
  2. 硬碟中或者網路傳輸用utf-8,網路I/O延遲或磁碟I/O延遲要遠大與utf-8的轉換延遲,而且I/O應該是儘可能地節省頻寬,保證資料傳輸的穩定性。

ps:使用者態和核心態,表示cpu的兩種執行狀態,核心態具有對作業系統的所有許可權。

ps:所有程序都跑在記憶體中,存資料其實是把記憶體中的資料刷到硬碟上,硬碟上不存在修改這麼一說,都是重寫。

ps:pycharm和普通的文字編輯器在從硬碟讀取資料到記憶體中時,是沒有任何區別的,只有在pycharm在對讀取到記憶體中的資料執行編譯的時候才有區別,這是他的特有功能。

 

2. 檔案操作

對檔案進行一系列的讀寫的操作。

2.1 檔案處理流程

1.開啟檔案,得到檔案控制代碼,並賦值給一個變數

2.通過控制代碼檔案進行操作

3.關閉檔案

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 f = open('a.txt','r',encoding='utf-8') #開啟檔案,字元編碼是utf-8,只讀
5 data = f.read()  #讀取檔案內所有內容,賦值給data
6 f.close()  # 關閉檔案,一般讀寫完成後都要關閉檔案

2.2 檔案開啟模式

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 f = open('開啟的檔名','開啟檔案的模式')

開啟檔案時,需要指定檔案路徑和以何等方式開啟檔案,開啟後,即可獲取該檔案控制代碼,日後通過此檔案控制代碼對該檔案操作。

開啟檔案的模式有:

  • r ,只讀模式【預設模式,檔案必須存在,不存在則丟擲異常】
  • w,只寫模式【不可讀;不存在則建立;存在則清空內容】
  • x, 只寫模式【不可讀;不存在則建立,存在則報錯】
  • a, 追加模式【可讀;   不存在則建立;存在則只追加內容】

"+" 表示可以同時讀寫某個檔案

  • r+, 讀寫【可讀,可寫】
  • w+,寫讀【可讀,可寫】
  • x+ ,寫讀【可讀,可寫】
  • a+, 寫讀【可讀,可寫】

 "b"表示以位元組的方式操作

  • rb  或 r+b
  • wb 或 w+b
  • xb 或 w+b
  • ab 或 a+b

 注:以b方式開啟時,讀取到的內容是位元組型別,寫入時也需要提供位元組型別,不能指定編碼

2.3 檔案內游標移動

注意:read(3)代表讀取3個字元,其餘的檔案內游標移動都是以位元組為單位如seek,tell,read,truncate

複製程式碼
1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 f = open('a.txt','r',encoding='utf-8')
4 f.seek(0,0) #表示從開始讀取
5 f.seek(0,1) #表示從當前位置開始讀取
6 f.seek(0,2) #表示從檔案結尾
7 data = f.readline()
8 f.close()
複製程式碼

ps:seek()代表一次移動幾個位元組,如果是用b模式開啟,seek()裡面可以有負數,例如seek(-1,2)

2.4 open函式語法詳解

1. open()語法

open(file[, mode[, buffering[, encoding[, errors[, newline[, closefd=True]]]]]])
open函式有很多的引數,常用的是file,mode和encoding
file檔案位置,需要加引號
mode檔案開啟模式,見下面3
buffering的可取值有0,1,>1三個,0代表buffer關閉(只適用於二進位制模式),1代表line buffer(只適用於文字模式),>1表示初始化的buffer大小;
encoding表示的是返回的資料採用何種編碼,一般採用utf8或者gbk;
errors的取值一般有strict,ignore,當取strict的時候,字元編碼出現問題的時候,會報錯,當取ignore的時候,編碼出現問題,程式會忽略而過,繼續執行下面的程式。
newline可以取的值有None, \n, \r, ”, ‘\r\n',用於區分換行符,但是這個引數只對文字模式有效;
closefd的取值,是與傳入的檔案引數有關,預設情況下為True,傳入的file引數為檔案的檔名,取值為False的時候,file只能是檔案描述符,什麼是檔案描述符,就是一個非負整數,在Unix核心的系統中,開啟一個檔案,便會返回一個檔案描述符。

2. Python中file()與open()區別
兩者都能夠開啟檔案,對檔案進行操作,也具有相似的用法和引數,但是,這兩種檔案開啟方式有本質的區別,file為檔案類,用file()來開啟檔案,相當於這是在構造檔案類,而用open()開啟檔案,是用python的內建函式來操作,建議使用open

3. 引數mode的基本取值

Character Meaning
‘r' open for reading (default)
‘w' open for writing, truncating the file first
‘a' open for writing, appending to the end of the file if it exists
‘b' binary mode
‘t' text mode (default)
‘+' open a disk file for updating (reading and writing)
‘U' universal newline mode (for backwards compatibility; should not be used in new code)

r、w、a為開啟檔案的基本模式,對應著只讀、只寫、追加模式;
b、t、+、U這四個字元,與以上的檔案開啟模式組合使用,二進位制模式,文字模式,讀寫模式、通用換行符,根據實際情況組合使用、

常見的mode取值組合

複製程式碼
#/usr/bin/env python
# -*- coding:utf-8 -*-
r或rt 預設模式,文字模式讀
rb   二進位制檔案
    
w或wt 文字模式寫,開啟前檔案儲存被清空
wb  二進位制寫,檔案儲存同樣被清空
    
a  追加模式,只能寫在檔案末尾
a+ 可讀寫模式,寫只能寫在檔案末尾
    
w+ 可讀寫,與a+的區別是要清空檔案內容
r+ 可讀寫,與a+的區別是可以寫到檔案任何位置
複製程式碼

2.5 檔案操作一些方法

複製程式碼
 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 f = open('a','r',encoding='utf-8')
 4 data = f.read() #全部讀取,檔案過大不建議使用這個
 5 data = f.readline() #讀取一行,游標移動到下一行
 6 data = f.readlines() #全部讀取,列表形式
 7 print(f.close) # 檔案是否關閉,返回True 或者False
 8 print(f.name) # 返回檔案的名字
 9 print(f.readable) # 是否可讀,返回True 或者 False
10 print(f.tell()) # 返回游標的位置
11 print(f.wirteable) # 檔案是否可寫,返回True 或者False
12 f.close()
複製程式碼

2.6 上下文管理

不用關閉檔案,自動幫你管理

1 with open('a.txt','w') as f:
2     pass
3 
4 with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
5     data=read_f.read()
6     write_f.write(data)

2.7 檔案的修改

複製程式碼
 1 import os
 2 with open('a.txt','r',encoding='utf-8') as read_f,\
 3         open('.a.txt.swap','w',encoding='utf-8') as write_f:
 4     for line in read_f:
 5         if line.startswith('hello'):
 6             line='厲害了,我的哥\n'
 7         write_f.write(line)
 8 
 9 os.remove('a.txt')
10 os.rename('.a.txt.swap','a.txt')
複製程式碼

 

3 函式

首先,為什麼要使用函式呢,因為函式有以下好處:

1.程式碼重用

2.保持一致性,易維護

3.可擴充套件性

在python中 函式是什麼呢,函式就相當於一些工具,因此,我們所知道的內建函式,就相當於python提供給我們的便利的使用工具,不需要在去具體寫,例如max(2,3),就可以很方便的得出誰最大,這樣是很便利的,但是python提供的方法呢,並不能夠滿足我們的所有需求,所以,我們可以自定義函式。因此有了自定義函式。

3.1 函式分類

內建函式和自定義函式

3.2 函式和過程

過程定義:過程就是簡單特殊沒有返回值的函式

這麼看來我們在討論為何使用函式的的時候引入的函式,都沒有返回值,沒有返回值就是過程,沒錯,但是在python中有比較神奇的事情

複製程式碼
 1 def test01():
 2     msg='hello The little green frog'
 3     print msg
 4  
 5 def test02():
 6     msg='hello WuDaLang'
 7     print msg
 8     return msg
 9  
10  
11 t1=test01()
12  
13 t2=test02()
14  
15  
16 print 'from test01 return is [%s]' %t1
17 print 'from test02 return is [%s]' %t2
複製程式碼

ps:函式None的三種情況:

1.不寫return 預設返回None

2.return 預設返回None

3.return None 返回None

ps:函式有些可以不寫返回值,如果只是做一些操作,例如print操作結果之類的,有些則需要返回值,比如像比大小一些功能,則需要返回值。

 

3.3 函式引數

函式引數的分類:無參函式(一般不需要傳引數的操作),位置引數,關鍵字引數,可變長引數

1.形參變數只有在被呼叫時才分配記憶體單元,在呼叫結束時,即刻釋放所分配的記憶體單元。因此,形參只在函式內部有效。函式呼叫結束返回主呼叫函式後則不能再使用該形參變數

2.實參可以是常量、變數、表示式、函式等,無論實參是何種型別的量,在進行函式呼叫時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使引數獲得確定值

3.3.1 無參函式

無參函式,顧名思義,就是函式沒有傳入引數

 1 def foo():

2 print('這是個無參函式')# 這個函式只是執行列印的功能,不需要傳入引數 

3.3.2 位置引數

直接上程式碼

1 def foo(x,y,z):
2   res = x+y+z
3   return res
4 
5 foo(1,2,3) #呼叫foo()函式
6   

ps:形參沒有一一對應這個概念,只有實參才有一一對應這個概念,對應形參。

3.3.3 關鍵字引數

直接上程式碼

1 def foo(x,y):
2   res = x+y
3   return res
4 
5 print(foo(x=1,y=2)) 

ps:關鍵字引數位置無需固定

ps:傳參的時候一般先是位置引數,如果有預設引數則跟在位置引數後邊

3.3.4 可變長引數

直接上程式碼

複製程式碼
def foo(*args):
   for i in args:
res += i return res print(foo(1,2,3,4,5,6,7,8))

def foo2(**kwargs):
print(kwargs)

foo2(x=1,y=2,c=3,b=4,k=8)

def foo3(*args,**kwargs):
print(args)
print(kwargs)

foo3(1,2,3,x=6,y=7,b=8)
複製程式碼

 ps:foo(*[1,2,3,4,5])  <=============>foo(1,2,3,4,5) 只要是*,全部打散了轉化成位置引數

 ps:foo(**{'x':1,'y':2}) <=============>foo(x=1,y=2) 只要是**,全部轉化成關鍵字引數

3.3.5 解壓

複製程式碼
a,_,b = (1,2,3,)
print(a)
print(b) # 只輸出 a 和 b _ 相當於佔位

c,*_,d = (1,2,3,4,5,6,7,8,9)
print(c)
print(d) #只輸出c 和 d 
複製程式碼

3.3.6 函式的使用方式

1.當成語句使用

2.當表示式使用

3.當作引數使用(巢狀)

複製程式碼
def foo(x,y):
   res = x if x > y else y
   return res

b = foo(2,5)

a = foo(2,5)**2 #表示式使用
 
b = foo(foo(2,5),8) #當作引數使用
複製程式碼

ps:空函式,據說很有用

複製程式碼
 1 def select():
 2    pass
 3 
 4 def insert():
 5    pass
 6 
 7 def update():
 8    pass
 9 
10 def delete():
11    pass
複製程式碼