Python學習筆記:檔案操作、類基礎、派生與繼承入門
#檔案操作open、close
開啟一個檔案供讀寫
file = open(file, mode=xx)
用完之後一定要記得關閉
file.close()
#檔案的方法:
file.readline():通常只對文字檔案進行讀取,讀到檔案為返回空字串,會返回回車符等轉義字元
file.readlines(lines):讀取 lines 行的資料,返回每一行資料字串組成的列表
file.read(size):讀取指定位元組數的資料,返回每個位元組字元組成的列表
file.read():讀取檔案中所有剩餘的位元組數,返回一個大的字串
file.writelines([a,b,c]):將字串列表寫入檔案,不自動加回車
file.flush():將緩衝區的檔案緩衝寫入磁碟
#檔案的開啟方式
't':文字檔案方式開啟
'r':只讀,預設值
'w':只寫,刪除原始檔內容;若不存在則建立
'x':建立一個新檔案,並以寫模式開啟這個檔案
'a':以只寫模式開啟一個檔案,在原檔案後面追加
#二進位制檔案
檔案中以位元組為儲存的單位,不以字元為單位進行儲存的檔案
以bytes進行儲存
#二進位制檔案操作方法
開啟時用模式'b'開啟
file.read(size=-1):讀取二進位制檔案size位元組,而不是size個字元
#位元組串,也叫位元組序列bytes
作用:儲存以位元組為單位的資料
位元組串是不可變的位元組序列
位元組串中每個元素是0-255之間的整數
#位元組串操作
建立新的位元組串:b''
建立非空位元組串:b'ABCD' b"ABCD" b"""ABCD""" b'''ABCD''' b'\x41\x11'
#位元組串的生成函式
bytes():生成一個空位元組串等同於b''
bytes(整型list):用可迭代物件初始化一個字串
bytes(整數n):生成值為0,長為n的位元組串
bytes(str,encoding='utf-8')
#位元組串的運算
+ += * *= 和字串完全相同
< <= > >= == !=
in / not in
索引/切片
#bytes與str的區別
bytes儲存位元組(0-255)
str儲存Unicode字元(0-65536)
可以相互轉換
b = s.encode(encoding='utf-8')
s = b.decode(encoding='utf-8')
#位元組陣列bytearray
可變的位元組序列
#bytearray建立函式
bytearray():建立空的位元組陣列
bytearray(整數n):建立長度為n的、值為0的位元組陣列
bytearray(整數可迭代物件)
bytearrar(字串,encoding="utf-8)
#bytearray操作方式與list完全相同
+ += * *=
< <= > >= == !=
in / not in
索引/切片
#檔案讀寫其他方法
file.tell():返回當前檔案流的絕對位置
file.seek(offset, whence = 0):
改變檔案指標的位置,相對於whence位置改變offset
whence:0:檔案頭 1:當前檔案指標位置 2:檔案末尾
#sys.stdin stdout stderr
這三個檔案一開始就已經加入緩衝區
sys.stdout是一個物件,綁定了一個檔案流物件,可以用檔案流檔案的所有方法
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
向file的檔案流物件中寫入資料,flush代表立即寫入檔案還是寫入緩衝區
sys.stderr是一個物件,綁定了一個錯誤流檔案,向該檔案寫錯誤資訊,包括raise觸發的錯誤
#重定向
python test.py 2> a.txt
檔案 檔案描述符
輸入檔案 0
輸出檔案 1
錯誤輸出檔案 2
#練習:實現檔案拷貝
def file_copy(src, dst, new_name):
src_file = open(src, 'rb')
if not dst.endswith('/'):
dst += '/'+ new_name
else:
dst += new_name
dst_file = open(dst,'wb')
while True:
read_data = src_file.read(1000)
if read_data == b'':
break
print("write %d bytes", dst_file.write(read_data))
src_file.close()
dst_file.close()
import os,sys
if len(sys.argv) != 4:
raise ValueError("This function need 3 param, %d is given" % (len(sys.argv)-1))
file_copy(sys.argv[1], sys.argv[2], sys.argv[3])
#呼叫方式:python test.py ./file.txt ./copy_test/ new_copy_file.txt
#註釋:python test.py 原始檔目錄+檔名 目標檔案路徑 目標檔案檔名
#類class
類是同來描述物件屬性和行為的工具,用類可以建立物件
#類的建立
class class_name(繼承列表):
"""文件字串
"""
例項方法
類變數
類方法@aclassmethod
靜態方法@staticmethod
說明:
類名必須是識別符號
類名實質上就是變數,它綁定了一個類
(潛規則)類的定義後要加兩個空行,告訴直譯器類定義完成;否則在極少數情況下無法解析
例項物件建立:類名(傳參列表)
例項有自己的名字空間,可以為一個例項新增變數(例項變數/方法)
#新增例項物件(直接新增即可)
class Cat():
pass
cat1 = Cat()
cat1.kinds = "erha"
#首次賦值建立例項變數,再次賦值改變引用關係
#刪除例項變數
del 例項.變數
#刪除例項
del 例項
#del作用總結
1、刪除變數
2、刪除列表中元素
3、刪除字典中鍵值對
4、刪除例項屬性
#例項方法
class class_name(繼承列表):
def 例項方法名(self, argv1, argv2, ...):
"""文件字串
"""
語句塊
說明:
例項方法第一個引數代表自己,一般用self命名
#呼叫例項方法
例項.方法(引數列表)
或
類名.方法(例項,引數列表)
#初始化方法
作用:建立物件時進行初始化
語法:
class class_name(繼承列表):
def __init__(self[,引數列表]):
語句塊
說明:
1、初始化方法名必須為__init__
2、一個類中只能有一個__init__方法
3、在例項建立後自動呼叫
4、如果需要return,必須return None
#階段示例:
class Animal():
def __init__(self, str_name):
self.name = str_name
def eat(self, food_name):
print("%s is eating %s" % (self.name, food_name))
def drink(self, drink_name):
print("%s is drinking %s" % (self.name, drink_name))
cat = Animal("cat")
dog = Animal("dog")
cat.eat("cookie")
dog.drink("orange")
#類變數
在class中建立的變數,屬於這個類,不屬於此類的例項
類變數可以通過該類直接訪問
類變數可以通過類的例項間接訪問
類變數可以通過例項的__class__屬性間接訪問
示例:
class Animal():
type_num = 0
cat = Animal()
print(Animal.type_num)
print(cat.type_num) #這種方法得到的name只是其引用,只能對其操作,但是不能用=,=會更改繫結關係,相當為cat建立例項變數type_num
print(cat.__class__.type_num)
#預製的例項屬性
__dict__屬性:繫結一個儲存此例項變數(屬性)的字典
示例:cat = Cat()
cat.name = 'cat'
則cat.__dict__ 為 {'name':'dog'}
__class__屬性:繫結建立此例項的類物件
例項:cat = Cat()
cat.name = 'cat'
則cat.__class__ 為 <class '__main__.Animal'>
作用:藉助此屬性建立同類物件(基本沒用)
藉助此屬性訪問類變數
__doc__屬性:繫結文件字串
__slots__列表:
作用:
1、限定一個類建立的例項只能由固定的例項變數
2、不允許物件新增此列表以外的例項屬性
3、防止使用者因寫錯屬性名,引發錯誤
說明:
含有__slots__列表的類所建立的例項物件沒有__dict__字典,即此例項不用字典來儲存例項變數
class Student():
__slots__ = ["name", "age"]
s.name = 'asd' #對的
s.Name = 'asd' #報錯
#關於類的系統內建函式
isinstance(obj, class_or_tuple) 返回該物件的obj是否是某個或者某些類其中的一個類建立的,如果是,返回True;否則返回Flase
type(obj):返回例項的型別
#類的類方法:僅屬於類的方法,要用@classmethod來修飾;類方法只能訪問類變數
第一個方法預設是類,約定為cls
說明:類和例項物件都能夠呼叫類內的方法
類方法不能訪問物件的例項變數
class A:
v = 0
@classmethod
def set_v(cls,value)
cls.v = value
A.set_v(100)
例項變數也可以建立同名的類變數,但是會為例項建立一個新變數
#靜態方法:
用@staticmethod修飾器來修飾
不能傳入self / cls, 只能定義在函式內部
類和例項都可以呼叫,不能訪問類變數和例項變數
示例:
class A():
@staticmethod
def mymax(a,b):
return max(a,b)
A.max(10,11)
a = A()
a.max(999,1000)
相當於普通函式,但是隻能通過類或者例項呼叫
也可以防止重名
#物件屬性管理函式
getaddr(obj, name[, default]):getaddr(x, y, default)相當於獲取x.y,如果不存在返回default,為給定default時,報錯
hasaddr(obj, name):判斷給定例項有沒有該屬性
setaddr(obj, name, value):設定obj.name = value
deladdr(obj, name):刪除物件obj中的name屬性,相當於del obj.name
#函式重寫 overwrite
讓自定義的類生成的物件(例項)能夠像內建物件一樣進行內建函式的操作
#重寫str方法
使得str(obj)能夠返回一個代表例項資訊的字串
示例:
class Student():
def __init__(self, n, a):
self.name = n
self.age = a
def __str__(self):
s = "%s is %d years old this year" % (self.name, self.age)
return s
a = Student("xiaozhang", 32)
print(a)
#或者str(a)
>>>xiaozhang is 32 years old this year
#repr & str
str(obj)將物件轉換為字串給人看
repr(obj)返回建立物件的表示式,可以用於遠端傳輸物件
如果str物件沒有重寫,呼叫repr返回的結果
示例:
class Student():
def __init__(self, n, a):
self.name = n
self.age =a
def __str__(self):
s = "%s is %d years old this year" % (self.name ,self.age)
return s
def __repr__(self):
return "Student(%r, %d)" % (self.name, self.age)
#在repr重寫時,用%r輸出字串
a = Student("xiaozhang", 32)
print(a)
print(str(a))
print(repr(a))
結果為:
xiaozhang is 32 years old this year
xiaozhang is 32 years old this year
Student(xiaozhang, 32)
#內建函式重寫
__abs__ -> abs(obj)
__len__ -> len(obj)
__reversed__ -> reversed()
__round__ round(obj)
#不重寫用不了
數值轉換重寫
__complex__
__int__
__float__
__bool__
#__bool__方法重寫:
如果沒有重寫,將呼叫__len__方法;如果沒有__len__方法,返回true
#高階迭代器
什麼是迭代器:通過next(it)函式取值的物件就是迭代器
迭代器協議:指物件能夠使用next函式取下一項資料,在沒有下一項資料是出啊發StopIterable異常來終止迭代的約定
迭代器協議的實現方法:
在類中需要__next__(self)函式重寫
程式碼:
class IntIterator():
def __init__(self, start_, stop_, step_ = 1):
self.start = start_
self.stop = stop_
if step_ == 0:
raise ValueError("step_ cannot be 0")
self.step = step_
def __next__(self):
if self.step < 0:
if self.start + self.step >= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
if self.step > 0:
if self.start + self.step <= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
it = IntIterator(1,13,1)
while True:
try:
print(next(it))
except:
break
#什麼是可迭代物件:
用iter(obj)函式返回的物件
可迭代物件內部需要定義__iter__(obj)方法來返回迭代器物件
可迭代物件能用於for迴圈,而迭代器不能
可迭代物件的存在就是為了在for迴圈中方便的使用,for迴圈自動呼叫可迭代物件類中的__iter__()方法,然後用next函式獲取迭代器下一個值,且產生StopIteration時不會觸發異常
#示例程式碼:
class IntIterator():
def __init__(self, start_, stop_, step_ = 1):
self.start = start_
self.stop = stop_
if step_ == 0:
raise ValueError("step_ cannot be 0")
self.step = step_
def __next__(self):
if self.step < 0:
if self.start + self.step >= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
if self.step > 0:
if self.start + self.step <= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
class MyInteger():
def __init__(self, start_num, stop_num):
self.start = start_num
self.end = stop_num
def __iter__(self):
return IntIterator(self.start, self.end)
for x in MyInteger(10,20):
print(x)
前面的簡單的yeild迭代器函式,會被轉化為一個可迭代物件類
#異常(高階)
#with語句
with 表示式1 [as 變數1], 表示式2 [as 變數2] ...:
語句塊
作用:用於對資源訪問的場合,確保過程中是否發生錯誤都能夠執行必要的資源釋放工作
用處:常用於檔案的開啟和關閉,執行緒中鎖的自動獲取與釋放
例子:with語句實現拷貝檔案
def file_copy(src, dst):
with open(src, 'rb') as src_file, open(dst, 'wb') as dst_file:
data = src_file.read(1000)
if data == '':
return
dst_file.write(data)
import sys
if len(sys.argv) != 3:
raise ValueError("Script only takes and only takes 4 arguments")
file_copy(sys.argv[1], sys.argv[2])
#技巧:文字檔案流檔案也是一個可迭代物件,可以用
for x in file:
x代表一行
#環境管理器
1、有__enter__和__exit__方法的類所生成的物件叫做環境管理器
2、能夠用with語句進行管理的物件必須是環境管理器
3、進入with語句時,自動呼叫__enter__()並將返回的物件給as的變數,所以__enter__()必須返回一個該類物件self;退出with語句時,自動呼叫__exit__()方法;
4、__exit__(self, exc_type, exc_value, exc_tb):當退出時自動呼叫
如果發生了異常,exc_type繫結異常型別,exc_value繫結物件
沒有發生異常時,exc_type繫結None,exc_value繫結None
exc_tb繫結traceback 一般不用
示例:
class Cooker():
def doworks(self):
print("Doing work")
def open_gas(self):
print("Opening gas")
def close_gas(self):
print("Closing gas")
def __enter__(self):
self.open_gas()
return self
def __exit__(self, exc_type, exc_value, exc_tb):
self.close_gas()
with Cooker() as cook:
raise ValueError
#繼承、派生
作用:
1、將類的公有功能實現在基類中,實現程式碼共享
2、不改變超類的程式碼的基礎上,改變原有類的功能
#名詞
基類(base class)= 超類(super class)= 父類(father class)
派生類(derived class) = 子類(child class)
#單繼承語法
class class_name(父類):
...
#示例程式碼:
class Human():
def eat(self):
print("Eating")
def walk(self):
print("Walking")
class Student(Human):
def study(self ):
print("Studying")
def eat(self):
print("Student is eating")
s = Student()
s.eat()
s.study()
s.walk()
#將類的公有功能實現在基類中,實現程式碼共享:Student可以使用Human的方法
#不改變超類的程式碼的基礎上,改變原有類的功能:Student重寫了自己的eat方法,改變了父類的功能
#繼承說明
一切類都繼承自object類,object類是一切類的超類
#類的__base__屬性:
記錄該類的直系父類
#覆蓋override
子類中重新定義父類中的方法,呼叫時呼叫重寫後的方法,這種操作叫做覆蓋,override