Python-lesson 2 數(shù)據(jù)類型、字符編碼、文件處理

1、Cpython垃圾回收機(jī)制

什么是垃圾:當(dāng)一個(gè)值身上沒有人綁定任何變量名(該值的引用計(jì)數(shù)=0)時(shí),該值就是一個(gè)垃圾,會(huì)將該值內(nèi)存空間釋放掉。

引用計(jì)數(shù)增加
age=18 //18的引用計(jì)數(shù)等于1
x=age //18的引用計(jì)數(shù)等于2

引用計(jì)數(shù)減少
age=19 //18的引用計(jì)數(shù)等于1
del x //解除值與變量名的綁定關(guān)系;18的引用計(jì)數(shù)變?yōu)?

2、數(shù)據(jù)類型介紹

1、 為何數(shù)據(jù)要分不同的類型?
數(shù)據(jù)是用來表示狀態(tài)的,不同的狀態(tài)就應(yīng)該用不同的類型的數(shù)據(jù)去表示

2、數(shù)據(jù)類型
  數(shù)字(整形,長整形,浮點(diǎn)型,復(fù)數(shù))
  字符串
  字節(jié)串:在介紹字符編碼時(shí)介紹字節(jié)bytes類型
  列表
  元組
  字典
  集合

3、按照以下幾個(gè)點(diǎn)展開數(shù)據(jù)類型的學(xué)習(xí)
==========================基本使用============================
1、用途

2、定義方式

3、常用操作+內(nèi)置的方法

==========================該類型總結(jié)==========================
存一個(gè)值or存多個(gè)值

有序or無序

可變or不可變(1、可變:值變,id不變??勺?=不可hash 2、不可變:值變,id就變。不可變==可hash)

3、數(shù)字

1、整型int
  作用:年紀(jì),等級(jí),身份證號(hào),qq號(hào)等整型數(shù)字相關(guān)
  定義:age=10 #本質(zhì)age=int(10)

2、浮點(diǎn)型float
  作用:薪資,身高,體重,體質(zhì)參數(shù)等浮點(diǎn)數(shù)相關(guān)
salary=3000.3 #本質(zhì)salary=float(3000.3)

類型轉(zhuǎn)換
a=('123') //字符串類型
a=int('123') //字符串轉(zhuǎn)成整型類型
a=float('12.3') //字符串轉(zhuǎn)成浮點(diǎn)型

4、字符串

  1. 作用:名字,性別,國籍,地址等描述信息
    定義:在單引號(hào)\雙引號(hào)\三引號(hào)內(nèi),由一串字符組成
    類型總結(jié):字符串本質(zhì)是一個(gè)值,但可以按照索引取值,不可變類型

  2. 類型轉(zhuǎn)換
    可以把任意類型轉(zhuǎn)成字符串類型
    str(10.3)
    str([1,2,3])
    str({'x':1})

4.1 需要掌握的操作

  1. 切片(順頭不順尾,步長)
    msg='hello world'
    print(msg[0]) =h
    print(msg[-1]) =d
    print(msg[0:5]) =hello
    print(msg[0:]) =hello world //步長默認(rèn)為1
    print(msg[:]) =hello world
    print(msg[0:5:2]) =hlo //切片方向和步長方向要一致
    print(msg[-1:-5:-1]) =dlro
    print(msg[::-1]) =dlrow olleh //將字符串倒過來輸出

  2. 統(tǒng)計(jì)長度,統(tǒng)計(jì)的是字符的個(gè)數(shù)
    print(len(msg)) =11

  3. 成員運(yùn)算
    print('ho' in msg) =True
    print('ho' not in msg) =False

  4. strip:移除字符串左右兩邊的某些字符;lstrip去左邊字符;rstarip去右邊字符
    msg=' hello '
    print(msg.strip(' ')) =hello
    print(msg.strip()) =hello //strip括號(hào)內(nèi)什么都不寫,默認(rèn)去除的就是空格
    name=input('name>>>: ').strip() //輸入自動(dòng)取出兩邊空格
    msg='+-%/hello(+^*'
    print(msg.strip('+
    %/(_+^*')) =hello //指定范圍,包括所有符號(hào)

  5. 切分split:把有規(guī)律的字符串切成列表從而方便取值;rsplit:從右往左切
    info='egon:18:180:150'
    res=info.split(':') //以:為分隔符,split兩個(gè)參數(shù):第一個(gè)以...為分隔符,第二個(gè)切成幾部分
    print(res[1]) =18
    print(info.rsplit(':',1))

  6. 字符串的拼接操作join,join的列表里只能是字符串,不能是數(shù)字類型
    s1=':'.join(res) //創(chuàng)建空字符串,以冒號(hào)為分隔符,依次加入列表res

  7. startswith,endswith 判斷是否以xx開頭,判斷是否以xx結(jié)尾
    msg='alex is dsb'
    print(msg.startswith('alex'))
    print(msg.endswith('dsb'))

  8. format 變量傳值 的三種玩法
    msg='myname is {name} myage is {age}' .format(age=18,name='abc')
    msg1='myname is {name}{name} myage is {age}{age}{age}' .format(age=18,name='abc')
    print(msg) =myname is abc myage is 18
    print(msg1) =myname is abcabc myage is 181818

  9. replace替換
    msg='kevin is sb kevin kevin'
    print(msg.replace('kevin','sb')) =sb is sb sb sb
    print(msg.replace('kevin','sb',1)) =sb is sb kevin kevin

  10. isdigit,判斷是否為純數(shù)字,小數(shù)不是純數(shù)字
    print('11111'.isdigit()) =True
    res='11111'
    print(res.isdigit()) =True
    ========================以下了解即可========================

  11. count 統(tǒng)計(jì)個(gè)數(shù)
    msg='kevin is sb kevin kevin'
    print(msg.count('kevin')) =3

  12. find 找到某個(gè)字符,返回值為索引(序列號(hào)),返回-1為沒找到;rfind 從右邊找;與index功能類似,但是沒有的字符 index 會(huì)報(bào)錯(cuò),沒有返回值
    msg='xxxkevin is sb kevin kevin'
    print(msg.find('kevin')) =3
    print(msg.rfind('kevin')) =15

  13. center 以某字符居中顯示;ljust 居左顯示,rjust 居右顯示;zfill 用 0 填充
    print('egon'.center(50,'')) //50為寬度,以 * 填充
    print('egon'.ljust(50,'
    ')) //寬度為50,egon在左邊,右邊為*
    print('egon'.rjust(50,'')) //寬度為50,egon在右邊,左邊為
    print('egon'.zfill(50)) //只有寬度參數(shù),用 0填充,默認(rèn)字符居右

  14. captalize 將首字母大寫;swapcase大寫轉(zhuǎn)小寫,小寫轉(zhuǎn)大寫;title 單詞首字母大寫
    print('my name is kevin'.captalize()) =My name is kevin
    print('AaBbCc'.swapcase()) =aAbBcC
    print('my name is kevin'.title()) =My Name Is Kevin

  15. is 其它
    name='egon123'
    print(name.isalnum()) //字符串由字母或數(shù)字組成為True,有其它符號(hào)為False
    print(name.isalpha()) //字符串只由字母組成為True
    print(name.islower()) //全是小寫為True
    print(name.isupper()) //全是大寫為True
    print(name.isspace()) //全是空格為True
    print(name.istitle()) //單詞首字母大寫為True

4.2 練習(xí)

  • 寫代碼,有如下變量,請(qǐng)按照要求實(shí)現(xiàn)每個(gè)功能 (共6分,每小題各0.5分)
name = " aleX"
1)    移除 name 變量對(duì)應(yīng)的值兩邊的空格,并輸出處理結(jié)果
print(name.strip())
2)    判斷 name 變量對(duì)應(yīng)的值是否以 "al" 開頭,并輸出結(jié)果
print(name.startswith("al"))
3)    判斷 name 變量對(duì)應(yīng)的值是否以 "X" 結(jié)尾,并輸出結(jié)果
print(name.endswith("X"))
4)    將 name 變量對(duì)應(yīng)的值中的 “l(fā)” 替換為 “p”,并輸出結(jié)果
print(name.replace("l","p"))
5)    將 name 變量對(duì)應(yīng)的值根據(jù) “l(fā)” 分割,并輸出結(jié)果。
print(name.split("l"))
6)    將 name 變量對(duì)應(yīng)的值變大寫,并輸出結(jié)果
print(name.upper())
7)    將 name 變量對(duì)應(yīng)的值變小寫,并輸出結(jié)果
print(name.lower())
8)    請(qǐng)輸出 name 變量對(duì)應(yīng)的值的第 2 個(gè)字符?
print(name[1])
9)    請(qǐng)輸出 name 變量對(duì)應(yīng)的值的前 3 個(gè)字符?
print(name[:3])
10)    請(qǐng)輸出 name 變量對(duì)應(yīng)的值的后 2 個(gè)字符?
print(name[-2:])
11)    請(qǐng)輸出 name 變量對(duì)應(yīng)的值中 “e” 所在索引位置?
print(name.index("e"))
12)    獲取子序列,去掉最后一個(gè)字符。如: oldboy 則獲取 oldbo。
print(name[:-1])

5、列表

作用:記錄多個(gè)值
定義方式:在[ ]內(nèi)用逗號(hào)分隔開多個(gè)任意類型的值;原材料可以是字符串,列表,字典;可變類型

5.1 優(yōu)先掌握的操作:

1、按索引存取值(正向存取+反向存取);可存也可以修改;對(duì)于賦值操作必須是已存在的索引
l=['a','b','c','d','e']
print(l[0]) =a
print(l[-1]) =e
l[0]='A' //修改列表
print(l) =['A','b','c','d','e']

2、切片(顧頭不顧尾,步長),步長與字符串一樣;原列表不會(huì)修改
print(l[1:4]) =['b','c','d']

3、長度
print(len(l)) =5

4、成員運(yùn)算in和not in
print('a' in l) =True
print('sss' not in l) =True

5、追加&插入
l.append(333) //append最后追加
print(l) =['a','b','c','d','e','333']
l.insert(0,111) //第一個(gè)位置添加值
print(l) =['111','a','b','c','d','e']

6、刪除remove ,有返回值;del也可刪,但是沒有返回值;pop 剪切一個(gè)值,返回剪切的值
l.remove('a') //()內(nèi)為值,不能為索引
print(l) =['b','c','d','e']
del l[0] //[ ] 內(nèi)為索引
l.pop(0) // () 內(nèi)為索引,不指定索引默認(rèn)時(shí)-1
res=l.pop(0)
print(res) =a

7、循環(huán)
for item in l
print(item)

5.2 需要掌握的操作

1、count 統(tǒng)計(jì)次數(shù)
print(l.count('a')) =1

2、extend 一次性往列表末尾追加多個(gè)值,一個(gè)參數(shù):可以被 for 循環(huán)的列表
item=[1,2,3,4,5]
l.extend(item)
print(l) =['a','b','c','d','e',1,2,3,4,5]

3、index 找索引,以找到的第一個(gè)值為準(zhǔn),不存在的值會(huì)報(bào)錯(cuò),可以用成員運(yùn)算判斷查找的值是否存在,以避免報(bào)錯(cuò);列表沒有find
print(l.index('a')) =0
print(l.index('c',2,5)) =2 //指定查找范圍,第二個(gè)開始,第五個(gè)結(jié)束

4、sort 排序,默認(rèn)從小到大排序
l=[4,6,2,9,10,3,1]
l.sort()
print(l) =[1, 2, 3, 4, 6, 9, 10]
l.sort(reverse=True) //從大到小排序
print(l) =[10, 9, 6, 4, 3, 2, 1]

6、元組

作用:就是一個(gè)不可變的列表(是可以當(dāng)做字典的key的),主要是用來讀

定義:在()內(nèi)用逗號(hào)分隔開多個(gè)任意類型的元素
t=(1,2,3,('a','b'),['q','w','e'])
本質(zhì)age=tuple(t=(1,2,3,('a','b'),['q','w','e']))
如果元組只有一個(gè)值,必須加一個(gè)逗號(hào)
t=('a',)

元組總結(jié)
1、存多個(gè)值
2、有序
3、不可變

6.1 優(yōu)先掌握的操作

1、按索引取值(正向取+反向取):只能取,不能添加、減少、修改
t=(1,2,3,('a','b'),['q','w','e'])
print(t[0]) =1
print(t[-1]) =['q','w','e']

2、切片(顧頭不顧尾,步長),步長與字符串一致
print(t[1:4]) =(2, 3, ('a', 'b'))

3、長度
print(len(t)) =5

4、成員運(yùn)算in和not in
print(1 in t) =True

5、循環(huán)
for item in t:
print(item)

6.2 需要掌握的操作

t=(1,2,3,('a','b'),3,['q','w','e'])

  1. 取索引
    print(t.index(3)) =2
    print(t.index(3,3,5)) =4 //指定范圍,以3開始,以5結(jié)束

  2. 統(tǒng)計(jì)個(gè)數(shù)
    print(t.count(3)) =2

7、字典

作用:記錄多個(gè)值,key對(duì)應(yīng)值,key對(duì)value有描述性功能;取值速度快

定義:在{ } 內(nèi)用逗號(hào)隔開多個(gè)元素,每個(gè)元素都是key:value的形式;key必須是不可變類型,value可以是任意類型

info={'name':'egon','age':18,'sex':'male'}
本質(zhì)
info=dict(name='egon',age=18,sex='male')

info=dict([['name','egon'],('age',18)])

{}.fromkeys(('name','age','sex'),None)

總結(jié)
1、存多個(gè)值
2、無序
3、可變

7.1 優(yōu)先掌握的操作

1、將值導(dǎo)入字典

  • 第一種方法,必須剛好是兩個(gè)值
    item=[('name','egon'),('age','18'),('gender','male')]
    d=dict(item)
    print(d) ={'name': 'egon', 'age': '18', 'gender': 'male'}

  • 第二種方法,將列表的值導(dǎo)入字典
    keys=['name','egon','age','gender','male']
    d={}.fromkeys(keys,None) //初始化一個(gè)列表,value為None
    print(d) ={'name': None, 'egon': None, 'age': None, 'gender': None, 'male': None}

2、按key存取值:可存可取
dic={'name': 'egon', 'age': '18', 'gender': 'male'}
print(dic['name']) =egon //當(dāng)key不存在時(shí)會(huì)報(bào)錯(cuò)
print(dic.get('name')) =egon
print(dic.get('xxx')) =None //當(dāng)key不存在時(shí)會(huì)返回一個(gè)None
dic['name']='Egon' //修改value
dic['hight']=18 //如果key不存在,就是一個(gè)加值的操作
print(dic) ={'name': 'egon', 'age': '18', 'gender': 'male', 'hight': 18}

3、長度len,統(tǒng)計(jì)key:value的個(gè)數(shù); 不能有重復(fù)的key,后面的key會(huì)覆蓋前面的key
print(len(dic)) =3

4、成員運(yùn)算in和not in,以字典的key為準(zhǔn)
print('name' in dic) =True
print('dasda' not in dic) =True

5、刪除
第一種:del dic['name']
第二種:res=dic.pop('name') //根據(jù)key刪除,有返回值,返回值為key對(duì)應(yīng)的value值
第三種:res=dic.popitem() //隨機(jī)刪,返回值是(key:value),返回值格式是元組

6、鍵keys(),值values(),鍵值對(duì)items()
print(dic.keys()) =dict_keys(['name', 'age', 'gender']) //取索引
print(dic.values()) =dict_values(['egon', '18', 'male']) //取值
print(dic.items()) =dict_items([('name', 'egon'), ('age', '18'), ('gender', 'male')]) //取鍵值對(duì)

7、循環(huán)
for item in dic:
print(item) //輸出的是key

for item in dic.values():
print(item) //輸出的是值

for item in dic.items():
print(ietm) //輸出的是 (key:value) 的元組

7.2 需要掌握的操作

1、update 新字典中已經(jīng)存在的以新的為準(zhǔn),不存在的增加
dic={'name': 'egon', 'age': '18', 'gender': 'male'}
dic.update({'age':19,'hight':180})
print(dic) ={'name': 'egon', 'age': 19, 'gender': 'male', 'hight': 180}

2、setdefault 加入一個(gè)鍵值對(duì),如果key已存在,則保留字典里的原值,如果key不存在,則加入鍵值對(duì);返回字典里key對(duì)應(yīng)的value值

  • 當(dāng)key存在時(shí),不改原值,
    dic.setdefault('name',’EGON‘)
    print(dic) ={'name': 'egon', 'age': '18', 'gender': 'male'}
    res=dic.setdefault('name',’EGON‘)
    print(res) =egon //返回原值

  • 當(dāng)key不存在時(shí),增加新值,
    dic.setdefault('hight',180)
    print(dic) ={'name': 'egon', 'age': '18', 'gender': 'male', 'hight': 180}
    res=dic.setdefault('hight',180)
    print(res) =180

8、集合

作用:關(guān)系運(yùn)算,去重

定義方式:在{ }內(nèi)用逗號(hào)分隔開多個(gè)元素,但是元素的特點(diǎn)是
1、每個(gè)元素必須是不可變類型(可hash,可作為字典的key)
2、沒有重復(fù)的元素
3、無序

注意:集合的目的是將不同的值存放到一起,不同的集合間用來做關(guān)系運(yùn)算,無需糾結(jié)于集合中單個(gè)值

類型轉(zhuǎn)換
res=set('hello') //字符串轉(zhuǎn)集合
rds=set([1,'a','b']) //列表轉(zhuǎn)集合
print(res) ={'h', 'l', 'e', 'o'} //去重
print(rds) ={1, 'a', 'b'}

總結(jié):
1、有多個(gè)值
2、無序
3、可變

8.1 優(yōu)先掌握的操作

pythons={'alex','egon','yuanhao','wupeiqi','gangdan','biubiu'}
linuxs={'wupeiqi','oldboy','gangdan'}
1、長度len
2、成員運(yùn)算in和not in

3、合集
print(pythons | linuxs)

4、&交集
print(pythons & linuxs)

5、兩個(gè)集合差集,以第一個(gè)集合為準(zhǔn)
print(pythons - linuxs) //求只報(bào)名python的學(xué)生
print(linuxs - pythons) //求只報(bào)名linux的學(xué)生

6、對(duì)稱差集;求沒有報(bào)名兩門課程的學(xué)生
第一種:res=(pythons - linuxs) | (linuxs - pythons)
第二種:res=pythons ^ linuxs
print(res)

7、== ,集合值相等即可,無需順序一致
s1={1,2,3}
s2={3,2,1}
print(s1 == s2) =True

8、父集:>,>= ;子集:<,<=
s1={1,2,3}
s2={3,2,1,4,6}
print(s2 >= s1) =True
print(s1 <= s2) =True

8.2 需要掌握的操作

  1. update 更新
    s1={1,2,3}
    s1.update({3,4,5,6}) //更新集合,有重復(fù)去重
    print(s1) ={1, 2, 3, 4, 5, 6}

  2. pop 刪除,隨機(jī)刪,刪除一個(gè)
    print(s1.pop())

  3. remove 指定值刪除,沒有返回值,不存在的值會(huì)報(bào)錯(cuò)
    s1.remove(1)
    print(s1) ={2,3}

  4. discard 指定值刪除,不存在的值返回None
    s1.discard(1)

  5. add 添加,無順序添加
    s1.add(4)
    print(s1) ={1, 2, 3, 4}

  6. 去重;
    name=['egon','egon','egon','alex','alex','kevin']
    res=set(name) //列表導(dǎo)入集合
    new_name=list(set(name))
    這種方法局限性:
    1、只針對(duì)不可變類型
    2、不能保證原來的順序

  • 用for循環(huán)方式去重
new_name=[]
for dic in name:
    if dic not in new_name:
        new_name.append(dic)

print(new_name) =['egon', 'alex', 'kevin']

9、數(shù)據(jù)類型總結(jié)

  1. 按存儲(chǔ)空間的占用分(從低到高)
    數(shù)字
    字符串
    集合:無序,即無序存索引相關(guān)信息
    元組:有序,需要存索引相關(guān)信息,不可變
    列表:有序,需要存索引相關(guān)信息,可變,需要處理數(shù)據(jù)的增刪改
    字典:無序,需要存key與value映射的相關(guān)信息,可變,需要處理數(shù)據(jù)的增刪改

  2. 按存值個(gè)數(shù)區(qū)分:
    標(biāo)量/原子類型:數(shù)字,字符串
    容器類型 列表:元組,字典

  3. 按可變不可變區(qū)分:
    可變:列表,字典
    不可變:數(shù)字,字符串,元組

  4. 按訪問順序區(qū)分:
    直接訪問:數(shù)字
    順序訪問(序列類型):字符串,列表,元組
    key值訪問(映射類型):字典

10、字符編碼結(jié)論

  1. 編碼與解碼
    字符編碼成 unicode 格式的二進(jìn)制數(shù)存到內(nèi)存,把unicode格式的二進(jìn)制數(shù)轉(zhuǎn)成其它格式的二進(jìn)制數(shù)刷到硬盤;解碼則反過來

  2. 內(nèi)存中固定使用unicode編碼,我們唯一可以改變的是數(shù)據(jù)由內(nèi)存刷到硬盤時(shí)采用的編碼,應(yīng)該采用utf-8;
    unicode的特點(diǎn):
    1、可以識(shí)別萬國字符。
    2、與各種字符編碼的二進(jìn)制數(shù)字都有對(duì)應(yīng)關(guān)系。

  3. 解決亂碼問題的核心:
    字符當(dāng)初以什么編碼存的,就應(yīng)該以什么編碼去讀。

  4. 因?yàn)閜ython2默認(rèn)ASCII碼,python3默認(rèn)utf-8碼; 如果要讀gbk編碼文件,寫文件時(shí)要在開頭指定#coding:gbk ;其它編碼格式一樣;如果在文件頭指定編碼,pycharm文本編輯器會(huì)自動(dòng)轉(zhuǎn)換為指定的編碼格式,其它文本編輯器則不會(huì),需要手動(dòng)修改。

  5. python3中字符串用unicode存在內(nèi)存當(dāng)中。python2要在定義字符串前面加個(gè)u,意思是字符串指定unicode編碼存內(nèi)存;
    例如:x='上' 定義一個(gè)字符串;print(x) 打印這一步是將x指向的那塊新的內(nèi)存空間(非代碼所在的內(nèi)存空間)中的內(nèi)存,打印到終端;python3什么都不用做,python2需要這樣定義:x=u'上'

11、文件處理

介紹:計(jì)算機(jī)系統(tǒng)分為:計(jì)算機(jī)硬件,操作系統(tǒng),應(yīng)用程序三部分。

1、什么是文件?
文件是操作系統(tǒng)為應(yīng)用程序或者用戶提供一種操作硬盤的虛擬單位。
window系統(tǒng)默認(rèn)為GBK編碼

  • 強(qiáng)調(diào):
    文件是操作系統(tǒng)提供的虛擬單位
    應(yīng)用程序或者用戶對(duì)文件的讀寫操作其實(shí)都是向操作系統(tǒng)發(fā)送指令

2、為什么要用文件?
文件對(duì)應(yīng)的硬盤空間,如果需要考慮永久保存數(shù)據(jù)那必須使用文件

3、如何用文件?
(1)打開文件
f=open(r'D:\untitled1\a.txt',mode='r',encoding='utf-8')
第一個(gè)小r,表示原生的字符串,\沒有轉(zhuǎn)義的意思,防止\a、\n轉(zhuǎn)義
第二個(gè)小r,以讀的模式打開,rb以二進(jìn)制格式讀,rt會(huì)把文本文件二進(jìn)制解碼成unicode格式存到內(nèi)存,針對(duì)文本文件用rt模式;w為寫操作;
賦值給一個(gè)變量,變量指定該文件對(duì)象,文件對(duì)象占的是應(yīng)用程序的資源
(2)讀/寫文件

f.read()             //不適合讀大文件
強(qiáng)調(diào):在t模式下read(n),代表字符個(gè)數(shù),除此以外的模式都是以字節(jié)為單位
f.write()
f.readable()    //是否可讀
f.writeable()    //是否可寫
f.readlines()       //將文件以列表的方式顯示,列表每一個(gè)元素,就是文件的每一行;也不適合大文件
f.writelines()       //取出列表每個(gè)元素,連續(xù)寫入;括號(hào)內(nèi)為列表變量名
f.flush()             //立刻將文件內(nèi)容從內(nèi)存刷到硬盤
f.readline()    //一次讀一行

#例:一行一行讀 f 文件
with open('a.txt',mode='rb') as f:
for line in f:
    print(line)

(3)關(guān)閉文件
f.close() //向操作系統(tǒng)發(fā)送指令,讓操作系統(tǒng)關(guān)閉打開的文件,回收操作系統(tǒng)資源

  1. 上下文管理
    with 在文件讀寫完,會(huì)自動(dòng)關(guān)閉文件;f.close()
with open('a.txt',mode='rt',encoding='utf-8') as f:
    data=f.read()
    print(data)
---------------------------------------------------------------------
你好哈哈哈
hello

# 也可以打開多個(gè)文件,\表示下一行顯示,但并不換行
with open('a.txt',mode='rt',encoding='utf-8') as f,\ 
open('a.txt',mode='rt',encoding='utf-8') as wj:

11.1 文件的解碼與編碼

x='上'
#unicode的二進(jìn)制----->編碼encode----->gbk格式的二進(jìn)制
res=x.encode('gbk')
print(res,type(res))
b'\xc9\xcf' <class 'bytes'>        //res打印出來是gbk二進(jìn)制格式,類型為type類型

#unicode的二進(jìn)制<-----解碼encode<-----gbk格式的二進(jìn)制
m=res.decode('gbk')
print(m)
上

11.2 文件操作模式

1、控制文件讀寫操作模式
r 只讀模式,以該模式打開文件,當(dāng)文件不存在時(shí)報(bào)錯(cuò);
w 只寫模式,如果該文件存在則覆蓋,如果該文件不存在,創(chuàng)建新文件寫入;文件打開不關(guān)閉的情況下,連續(xù)寫入自動(dòng)追加;
a 追加,如果該文件存在則文件結(jié)尾追加內(nèi)容,如果該文件不存在,創(chuàng)建新文件寫入;
w+ 讀寫,如果該文件存在則覆蓋,如果該文件不存在,創(chuàng)建新文件寫入

2、控制文件讀寫內(nèi)容的模式(不能單獨(dú)使用,必須與r、w、a連用)
t (默認(rèn)) 讀寫只能是文本文件,都是字符串類型,會(huì)自動(dòng)解碼文本文件;必須指定encoding參數(shù)
b 對(duì)于非文本文件,我們只能使用b模式,linux可忽略;"b"表示以字節(jié)的方式操作;以b方式打開時(shí),讀取到的內(nèi)容是byte字節(jié)類型,寫入時(shí)也需要提供字節(jié)類型,不能指定編碼

with語句

為了避免打開文件后忘記關(guān)閉,可以通過管理上下文,即:
with open('log','r') as f:

3、文件的修改

  • 方式一:
    1、以讀的方式打開源文件
    2、將文件內(nèi)容一次性全讀入內(nèi)存,在內(nèi)存完成修改
    3、以寫的方式打開源文件,然后將修改后的結(jié)果一次性寫入源文件,再由內(nèi)存覆蓋到硬盤
    優(yōu)點(diǎn):在文件修改過程中硬盤只存在一份數(shù)據(jù)
    缺點(diǎn):浪費(fèi)內(nèi)存
with open('a.txt',mode='rt',encoding='utf-8') as f1:
    msg=f1.read()
    new_msg=msg.replace('alex','大SB')

with open('a.txt',mode='wt',encoding='utf-8') as f2:
    f2.write(new_msg)
  • 方式二:
    1、以讀的方式打開源文件,以寫的方式打開一個(gè)臨時(shí)文件
    2、讀取源文件的一行內(nèi)容到內(nèi)存中,將修改的結(jié)果寫入臨時(shí)文件,循環(huán)往復(fù)直到修改完成
    3、刪除源文件,將臨時(shí)文件重命名為源文件名
    優(yōu)點(diǎn):同一時(shí)間在內(nèi)存中只有文件的一行內(nèi)容,更節(jié)省內(nèi)存
    缺點(diǎn):在文件修改過程中硬盤存在兩份數(shù)據(jù)
    應(yīng)用場(chǎng)景:適合大文件,需要硬盤空間足夠
import os

with open('b.txt',mode='rt',encoding='utf-8') as read_f,\
    open('.b.txt.swap',mode='wt',encoding='utf-8') as write_f:
    for line in read_f:
        write_f.write(line.replace('大sB','alex'))
os.remove('b.txt')
os.rename('.b.txt.swap','b.txt')

11.3 文件指針移動(dòng)

f.seek(3,0) //3指移動(dòng)的字節(jié)數(shù),0是模式
1、三種模式,以字節(jié)為單位;只有0模式既可以在t模式下用也可以在b模式下用,而1、2兩種模式只能在b模式下用
0 (默認(rèn)模式):永遠(yuǎn)參照文件開頭往后數(shù)
1:參照指針當(dāng)前所在位置
2:參照文件末尾,倒著數(shù)

注意:t 模式下的read(n) 是以字符為單位;意思為從哪個(gè)字符開始讀

b.txt文件內(nèi)容
你好啊hello

# 0模式
with open('b.txt',mode='rt',encoding='utf-8') as f:
    f.seek(3,0)          
    print(f.tell())     //f.tell() 當(dāng)前指針位置,永遠(yuǎn)參照文件開頭
    print(f.read())    //基于當(dāng)前所在的位置讀
----------------------------
3
好啊hello

# 1模式
with open('b.txt',mode='rb') as f:
    f.read(2)          //是2個(gè)字節(jié)
    f.seek(4,1)     
    print(f.read().decode('utf-8'))           //從當(dāng)前字節(jié)開始讀
-------------------------------
啊hello

#2模式
with open('b.txt',mode='rb') as f:
    f.seek(-5,2)            //倒著移動(dòng)5個(gè)字節(jié)
    print(f.tell())
    print(f.read().decode('utf-8'))         //從當(dāng)前字節(jié)開始讀
---------------------------------
9
hello

# 小練習(xí),監(jiān)測(cè)access.log 日志文件,將新增內(nèi)容輸出
with open('access.log',mode='at',encoding='utf-8') as f:
    f.write('2011-11-11 11-11-11 alex結(jié)婚啦\n')         //模擬日志文件;access.log文件追加內(nèi)容   

import time                //導(dǎo)入時(shí)間模塊
with open('access.log',mode='rb') as f:
    f.seek(0,2)               //指針移到文件末尾
    while True:
        line=f.readline()
        if len(line)  == 0:
            time.sleep(0.1)
        else:
            print(line.decode('utf-8'),end='')

12、練習(xí)

  1. 有列表data=['alex',49,[1900,3,18]],分別取出列表中的名字,年齡,出生的年,月,日賦值給不同的變量
data=['alex',49,[1900,3,18]]
a=data[0]
b=data[1]
c=data[2]
print(a,b,c)
  1. 用列表模擬隊(duì)列
* 1. 隊(duì)列:先進(jìn)先出
l=[]
 #入隊(duì)
 l.append('first')
 l.append('second')
 l.append('third')
 print(l)
 #出隊(duì)
 print(l.pop(0))
 print(l.pop(0))
 print(l.pop(0))
  1. 用列表模擬堆棧
* 堆棧:后進(jìn)先出
l=[]
 #入棧
l.append('first')
l.append('second')
l.append('third')
print(l)
 #出棧
print(l.pop())
print(l.pop())
print(l.pop())
  1. 打印出金字塔
for i in range(0,5):
    for j in range(0,4-i):
        print(" ",end="")
    for k in range(i+1):
        print("* ",end="")
    print()

for i in range(0,5):
    for k in range(i + 1):
        print(" ",end="")
    for j in range(0, 4 - i):
        print("* ",end="")
    print()
  1. 99乘法表
for i in  range(1,10):
    for j in range(1,1+i):
        print("%s * %s = %-2s   " % (j , i ,i * j),end="")
    print()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容