open()函數,用來讀取或寫入文件,用法為
stream=open('文件路徑','操作方式')
可以對這個流進行文件內容的操作
更多操作模式如下
stream.readline()
返回的是文件裡一行的內容,且在使用後,文件的開始位置會變為下一行的起始位置,當無行可讀時,返回None
由於讀取的是行,所以會把行末尾的換行符也讀入,顯示出來便是print出來多了一個空行,但是最後一行沒有
stream.read()
返回全部內容
stream.readlines()
返回每一行的內容形成一個列表並返回
stream.write(str)
向文件中寫入,寫入後指針位置位於字符串尾
stream.write(list)
向文件中依次寫入list內的內容
os.remove(path)
刪除文件
os.rmdir(path)
刪除文件夾,但文件夾必須為空
os.listdir(path)
返回一個由該文件夾內所有文件名組成的列表
os.chdir(path)
切換當前目錄
os.getcwd(path)
返回當前目錄
os.splitext(path)
將文件路徑名和文件的類型分割開來,返回值是一個元組
os.split(path)
將文件路徑和文件名(含後綴)分割開來,返回值是一個元組
附上手寫的文件夾復制代碼
import os
def copydir(src,target):
filelist=os.listdir(src)
for file in filelist:
path=os.path.join(src,file)
if os.path.isdir(path):
path1=os.path.join(src,file)
path2=os.path.join(target,file)
if os.path.isdir(path2):
pass
else:
os.mkdir(path2)
copydir(path1,path2)
else:
with open(path,'rb') as stream:
container=stream.read()
path1=os.path.join(target,file)
with open(path1,'wb') as wstream:
wstream.write(container)
try...except
語句
當try語句內出現異常錯誤時,except會自動接受異常並執行except內的語句
可以使用多條except語句接受不同的異常類型
注意:except語句按照從上到下順序接受異常,且只接受一次,所以表示所有異常的Exception類要放在最後
try...except...else
語句
當無異常拋出時,便會執行else語句下的內容
try...except...finally
語句
無論是否有異常拋出,即使有崩潰產生,finally中的語句一定會執行,如果有返回值則會覆蓋掉之前的返回值
raise可以拋出一個自定義的異常,類型以及異常的具體內容自己定
使用方法為raise ExceptionName(str)
try:
a = input("輸入一個數:")
#判斷用戶輸入的是否為數字
if(not a.isdigit()):
raise ValueError("a 必須是數字")
except ValueError as e:
print("引發異常:",repr(e))
# repr() 返回將對象直接轉化為的字符串
在沒有引發過異常的程序使用無參的 raise 語句時,它默認引發的是 RuntimeError 異常
當之前已經使用過一個raise時,使用無參的 raise 語句默認引發和上一個相同的異常,但有多個的異常時默認引發的還是 RuntimeError 異常
可以通過類似列表推導式的方法,迭代出一系列的值,同時相對於直接的列表節約了大量空間
格式為
generator=(x for x in range(10))
和列表推導式的唯一區別就是[]
變成了()
使用時可以通過generator.__next()__
或者next(generator)
來迭代出下一個值
當超出迭代器的范圍時,再次調用會爆出StopIteration的錯誤
生成器的另一種方法是利用函數
def gen():
i = 0
while i<5:
temp = yield i
print(temp)
i+=1
當函數含有yield
關鍵字時,該函數代表的就是一個生成器,使用方法為f=gen()
,對這個f可以使用上述的一系列操作
yield
的作用是返回值的同時在此處暫停,同時當下一次調用該生成器時從這個斷點繼續運行
f.send(obj)
send函數的作用可以向生成器內傳入一個對象,對於如同temp = yield i
的語句作用是將該對象在斷點處賦值給temp並且運行下去,所以要注意的是在第一次調用生成器時不能使用send函數,正常使用f.__next__()
便相當於是f.send(None)
可以被next()函數調用並返回下一個元素的對象都能可以稱為迭代器
迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。
可以通過isinstance()
函數判斷是否是可迭代對象,注意要先from collections import Iterable
但是可迭代的對象不一定是迭代器,可以通過iter()
使他變成一個迭代器
創建一個類的格式
class name:
屬性1
屬性2
函數1:
函數2:
就是寫在類裡面的函數,可以通過類創建的實例對象調用,注意函數的第一個參數必須是self表示本身這個對象
在python中不支持函數名一樣但是參數不相同的函數,後面一個函數會覆蓋掉前面一個同名的函數
格式如下
def name(self,*args,*kwargs):
...
...
類方法與靜態方法都可以不依賴於對象使用,直接使用類名.函數
的格式調用,同時,操作的對象也只能是類的屬性
類方法的格式
def class:
@classmethod
def name(cls,*args,**kwargs):
...
...
類方法的第一個參數必須是cls,表示本類,使用時函數前必須添加@classmethod
關鍵字
靜態方法的格式
def class:
@staticmethod
def name(*args,*kwargs):
...
...
注意的是靜態方法不需要self或者是cls參數,但是便也不能使用任何的類的屬性和對象
可以類比構造函數,析構函數一類的
魔法方法的格式在開頭和結尾各有兩個下劃線不能捨棄,名字均為定義好的
__init(self)__
構造函數,創建對象時調用
__new(cls)__
構造函數,調用的優先級比init更高,參數是cls,必須有返回值,當返回值是一個當前類的對象時,init也會隨後被調用
__new()__也屬於類的靜態方法
__del()__
析構函數
__call()__
當使用創建的對象加括號時執行
__str()___
返回值是一個字符串,是當采用print()函數時打印出來的字符
__repr()__
功能與str類似,同時還是直接使用repr(obj)的返回值,與str的區別是repr(obj)的字符串會帶上雙引號
關於運算符的魔法方法,類比重載
注意這些用法基本均為__lt(self,obj)__
,記得傳入另一個比較項的參數名
類屬性所有創建的對象共用,實例化後的對象不可修改,只能通過類名.類屬性
方式修改,如果有同名實例屬性,實例對象會優先訪問實例屬性。
在屬性前加上兩個下劃線便為私有屬性,私有屬性外界無法直接修改和訪問,只能在類的方法內部使用,類比C++中的private關鍵字和public關鍵字
對於get,set等函數去對於私有屬性進行操作顯得有些麻煩,為了實現看上去直接對私有屬性的操作,可以使用property關鍵字
如
class Dog():
__age=1
def __init__(self):
self.__age=1
@property
def age(self):
return self.__age
@age.setter #名稱要和上面一個一樣
def age(self,age):
self.__age=age
d=Dog()
print(d.age) #直接訪問__age私有參數
d.age=2
print(d.age)
要注意的時只有在定義了property函數之後才可以使用setter關鍵字來指定輔助函數
引用就是在別的類中使用一個已創建的類,正常使用即可,注意傳入參數
繼承的格式為
class 子類名(父類名):
def __init__(self):
super().__init__()
當需要使用到父類的構造函數時,可以使用super()函數來調用父類的構造函數,注意父類的傳入參數不能缺少
當子類存在和父類相同函數名的函數時,會對父類的函數進行覆蓋,也可以使用super()來調用父類的方法
多繼承的語法格式
class 子類名(父類名1,父類名2...)
pass
如果不同的父類中存在同名的方法,子類對象在調用方法時,會調用最前面的一個父類的方法,實際中應當避免這種情況
python中針對類提供了一個內置屬性__mro__可以用來查看方法的搜索順序。
使用方法
print(C.__mro__)
結果為
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
在調用方法時,按照__mro__的輸出結果從左至右的順序查找。
如果再當前類中找到方法,就直接執行,不再向下搜索。
如果沒有找到,就順序查找下一個類中是否有對應的方法,如果找到了最後一個類,依然沒有找到方法,程序就會報錯。
通過某種方法,使得創建的對象共享的是一個地址,使得內存優化。
使用__new__()
class Singleton(object):
__instance=None
def __new__(cls):
if cls.__instance is None:
cls.__instance = super(Singleton, cls).__new__(cls)
return cls.__instance
obj1 = Singleton()
obj2 = Singleton()
使用裝飾器
def singleton(cls):
instances = {}
def getinstance(*args,**kwargs):
if cls not in instances:
instances[cls] = cls(*args,**kwargs)
return instances[cls]
return getinstance
@singleton
class MyClass:
a = 1
c1 = MyClass()
c2 = MyClass()
print(c1 == c2)
# 裝飾器 singleton返回了一個內部函數 getinstance,該函數會判斷某個類是否在字典 instances 中,如果不存在,則會將 cls 作為 key,cls(*args, **kw) 作為 value 存到 instances 中,否則,直接返回 instances[cls]。