Python的萬字學(xué)習(xí)筆記,持續(xù)更新中...
參考的視頻課程如下:
你覺得自己這輩子都學(xué)不會編程?超超超基礎(chǔ)Python課程,3小時快速入門 【自學(xué)Python教程合集】【3小時快速入門Python】
學(xué)習(xí)了一天粒粒老師的課程就通關(guān)了,講解的非常簡單易懂,有動畫做輔助很適合小白
【B站最全最易學(xué)】北京大學(xué)終于將Python整理成了漫畫書,漫畫教學(xué)更生動,小白一學(xué)就會,拿走不謝,允許白嫖??!
比較系統(tǒng)的講解了python的概念知識,作為一個補充來學(xué)習(xí)
建議剛學(xué)習(xí)的同學(xué)可以去第一個視頻學(xué)習(xí),然后再學(xué)習(xí)第二個視頻會少很多問題
print("""筆記內(nèi)容為本人學(xué)習(xí)的課堂筆記,結(jié)合自己搜索的例子,來解釋課程不清楚的地方
都是非常非常基礎(chǔ)的內(nèi)容,適合剛接觸這一塊的小伙伴一起學(xué)習(xí)
有問題也歡迎在評論區(qū)一起討論!""")
\ 轉(zhuǎn)義符?? 可以配合\'? 或者 \"一起用 來強調(diào)引號是字符的屬性
\n 指的是換行
"""_________""" 三引號 內(nèi)容自動換行,下面長字符串那里有例子
?
\t 水平制表符
\n 換行符
\r 回車
\” 雙引號 ??\’單引號 ??\\反斜杠
print("hel\\lo")
輸出為:hel\lo
這個例子里,直接寫成print(“he\llo”)是會報錯的,需要加上\轉(zhuǎn)義符
?
原始字符串
print(r"hel\\lo")
可以在最前方加上r來讓print的結(jié)果與””引號內(nèi)的內(nèi)容一樣
?
長字符串
使用三個”,或者”來講內(nèi)容括起來,會自動按照原始格式進行換行輸出
比如:
print("""春風(fēng)拂面,溫暖如綢,
花開如海,香氣襲人。
我走過綠茵的草地,
聽著鳥兒歌唱的旋律。""")
輸出為:
春風(fēng)拂面,溫暖如綢,
花開如海,香氣襲人。
我走過綠茵的草地,
聽著鳥兒歌唱的旋律。
?
字符串查找
a.find()函數(shù)可以用來查找字符串的索引值并且返回結(jié)果.
比如:
a ="春風(fēng)拂面,溫暖如綢,花開如海,香氣襲人。"
print(a.find("溫"))
輸出為: 5
還可以為搜索加上范圍,比如:a.find(“溫”,4,7),這樣會在索引值為4和6之間進行搜索
或者用a.find(“溫”,2) ,這樣就是從索引值為2開始一直找到最后一個索引值
如果返回值為-1,就是沒有找到需要搜索的字符串
?
字符串替換
可以用a.replace(“需替換”,”替換為”,數(shù)量)?? 數(shù)量為需要替換的個數(shù),也可以不加,替換所有
比如:
a ="春風(fēng)拂面,溫暖如綢,花開如海,香氣襲人。"
print(a.replace(",","!",1))
輸出為: 春風(fēng)拂面!溫暖如綢,花開如海,香氣襲人。
--------------------
變量
名稱中不能有空格,不能用數(shù)字開頭,不能有除了_下劃線以外的符號,不能用""引號包住,不能占用python關(guān)鍵字,比如print
變量名區(qū)分大小寫,
a="變量名"
print(a+"xxxx")
?
儲存變量
b=a
此時,可以給a賦予新的值
----------------------
運算
+-*/??? **(平方)比如2 ** 3 表示2的3次方
import math
math.函數(shù)名(數(shù)值)? --- math.sin(1)
-------------------------
#怕忘記了寫這個
用#放最前面做注釋
快捷鍵 ctrl+/? 選中代碼行 可以多選
-------------------------
數(shù)值類型
數(shù)字≠字符串 不需要用""引號包住
字符串str??? 可以用Len函數(shù)得到字符串長度 len('hello')--->5 轉(zhuǎn)義符\n只占一個長度??? "HELLO"[3] 01234 返回值為L? ,可以使用索引-1來表示最后一個元素 Print("HELLO[-1]") 就會輸出O
整數(shù)int
浮點數(shù)float(帶小數(shù)點的數(shù)字)
布爾類型bool???? 真和假? True False,注意開頭需要大寫
空值類型NoneType None 開頭注意大寫,不然不會識別,布爾也是開頭需要大寫
----------------------
python交互模式/命令行模式
在cmd用python進入
quit() 或者ctrl+d 退出
--------------
Input
輸入的值會被視為字符串,如果直接參與運算會報錯,
這里需要利用到int來將輸入的數(shù)字轉(zhuǎn)化為整數(shù)或者浮點數(shù),比如age = int(input("你今年的年齡"))
-----------------------
條件語句
if? True 或者False , 注意 if [條件]:????? 條件結(jié)束需要加上冒號:??????? else可以省略
如if [條件]:
????? [執(zhí)行語句]
????? [執(zhí)行語句]
else:
????? [執(zhí)行語句]????? 注意執(zhí)行語句需要有縮進,來讓系統(tǒng)判斷此條語句是歸if還是else來管
?
======
也可以用嵌套條件語句
比如
if [條件1]:
??? if[條件2]:
?????? [執(zhí)行語句]
??? else:
?????? [執(zhí)行語句]
======
elif語句,多個elif條件只會執(zhí)行首個被滿足的條件,后面的elif就不會被執(zhí)行了
如下,
if [條件1]:
?? [執(zhí)行語句1]
elif [條件2]:
?? [執(zhí)行語句2]
elif [條件3]:
?? [執(zhí)行語句3]
else:
?? [執(zhí)行語句4]
?
比較運算符 ==?? ,比如 3 ==3 --->True? |? "a" == "b" --->False
!= 不等于號,比如3 !=3 ---->False????? |?? "a" != "b"? ---->True
此外還有 > ,>= , <,<=
?
邏輯運算
and or not
優(yōu)先級not---->and---->or
可以用括號()改變運算順序
not(x>5 and (x <10 or x ==12))
?
方法和函數(shù)
方法用法是:對象.方法名(...)?? 比如list.append("手套")?? ---->往list里面添加手套
同時可以用以下兩種方法來追加多個元素,類似合并列表
a = ["a","b","c"]
b = ["g","h","k"]
b +=a
b.extend(a)
print(b)
?
函數(shù)的用法是:函數(shù)(對象)????? 比如len(list)??? ---------------->list的長度
?
python列表
list = ["1","2"] 中間用逗號隔開 這里列表中的數(shù)值類型可以是字符串,也可以是數(shù)字,如果是字符串的話需要加入引號"",數(shù)字則不用
列表是可變的,可以直接往里面添加新的元素
str,int,float,bool這類是不可變的,需要重新賦值才能變化
?
刪除列表的某個元素:list.remove("手套"),注意remove的元素需要存在于列表中,不然會報錯
列表可以存放不同類型的數(shù)據(jù),比如str,float,bool,none
?
list[1] = "戒指" ---->可以用索引來對列表中的元素進行賦值
?
列表可以配合max,min,sorted函數(shù)來使用
比如print(max(list_num)) 表示打印列表中最大的數(shù)
?????? print(min(list_num)) 表示打印列表中最小的數(shù)
?????? print(sorted(list_num)) 表示打印排序后的列表,從小到大,注意sorted不適用于字符串
---------------------------------------------
集合
創(chuàng)建空集合的方式為set() ?比如a = set() 而不用空的{},因為空的{}會默認(rèn)創(chuàng)建空字典
或者用 b = {1,2,3,”abc”}創(chuàng)建 ?用大括號
集合不會包括重復(fù)的元素,會將重復(fù)的元素歸一化,即使集合中有重復(fù)的元素,print時會自動去除重復(fù)的元素,集合中的元素是沒有順序的,
“”Item”” 是通常用作迭代過程中的變量名,表示集合(例如列表、元組、字典等)中的每個元素或鍵值對 ,可以替換成任意的名稱
my_list = [1, 2, 3, 4, 5]
for item in my_list:
??? print(item)
集合可以用add或者remove方法來添加和移除元素
比如
num= {1,2,3,4}
num.add(6)
num.remove(1)
print(num)
輸出結(jié)果為: {2, 3, 4, 6}
?
也可以用clear()的方法來清空集合,使之變?yōu)榭占?/p>
例如:
num= {1,2,3,4}
num.clear()
print(num)
結(jié)果為: set()
?
兩個集合是可以相互計算的,
交集 ?&或者intersection
并集 ?| 或者union
差集 ?- 或者difference
例如:
a = {1,2,3,4,"a"}
b = {3,4,5,6,"a"}
print(a&b)
print(a.intersection(b))
{'a', 3, 4}
?
可以在集合中使用In和not in的測試運算符
num= {1,2,3,4}
a = 1 in num
print(a)
結(jié)果為: True
?
?
---------------------------------------------
字典
鍵:值? key:value
Name = dict()創(chuàng)建空字典
Name = {“a”:1}
可以用a =[鍵名]來獲取值
比如:
a = {'agui': 123, 'xuge': 5565, 'sun': 777}
b = a["agui"]
print(b)
輸出為: 123
?
也可以通過a[鍵名] = 新值 來更改值的值
a = {'agui': 123, 'xuge': 5565, 'sun': 777}
a["agui"] = 321
print(a)
輸出為: {'agui': 321, 'xuge': 5565, 'sun': 777}
?
可以用pop()函數(shù)來刪除鍵值
比如:
a = {'agui': 123, 'xuge': 5565, 'sun': 777}
a.pop("agui")
print(a)
輸出為: {'xuge': 5565, 'sun': 777}
?
比如 list = {"手套":"15元",}
鍵的類型必須是不可變的,列表是可變的,所以不能作為鍵來使用,str,int,float,bool等是可變的數(shù)據(jù)類型,可以作為鍵來使用
字典和列表一樣都是可以改變的,比如需要往字典里添加元素
list = ["帽子"] = "85元"
如果需要print 字典 ,則需要將字典用str轉(zhuǎn)化為字符串
?
如果需要刪除字典的鍵值可以用
del list = ["帽子"] ,此時會刪除鍵和相對應(yīng)的值,如果鍵本身不存在的話就會報錯
len函數(shù)同樣適用于字典
如果只想要輸出鍵的話可以用dict.keys() 方法
如果只想要輸出值的話可以用dict.values() 方法
如果想要輸出鍵和值的話可以用dict.items() 方法
舉例:
keys_dict = dict(my_dict.keys())
print(keys_dict)
?
元組Tuple,
不可變,但是和列表很相似的數(shù)據(jù)結(jié)構(gòu),可以用作復(fù)雜的鍵來使用
比如 list = ("手套","帽子")????? 和列表的區(qū)別是,列表用的是[],元組的用的是(),由于是不可變的數(shù)據(jù)類型,所以append和remove都是不適用于元組的
當(dāng)詞典里"手套"的種類有若干時,可以用元組的方式來區(qū)分手套
list = {("手套","高"):"175元",
????????? ("手套","中"):"100元",
????????? ("手套","低"):"50元"}
創(chuàng)建元組的幾種方式
可以用tuple()函數(shù),或者1,來創(chuàng)建只有一個元素的元組? 或者(1,3,4,5,6)?? 亦或者1,3,45,6?
用a =()可以創(chuàng)建空的元組
?
?
a = tuple("hello")
b = 1,
c = (1,3,4,5)
d = 1,2,34,5
e = ()
print(a)
print(b)
print(c)
print(d)
print(e)
print(type(a))
print(type(b))
print(type(c))
print(type(d))
print(type(e))
('h', 'e', 'l', 'l', 'o')
(1,)
(1, 3, 4, 5)
(1, 2, 34, 5)
()
<class 'tuple'>
<class 'tuple'>
<class 'tuple'>
<class 'tuple'>
<class 'tuple'>
?
由于元組是不可變的,所以不能對元組進行修改、添加或刪除元素的操作。如果需要修改元組中的元素,可以先將元組轉(zhuǎn)換為列表進行修改,然后再轉(zhuǎn)換回元組。
?
另外元組也可以用2個以上的元組來組成新的元組,比如
a = (1,2,3)
b =(4,5,6)
c= (7,8,9)
d =(a,b,c)
print(d)
結(jié)果為: ((1, 2, 3), (4, 5, 6), (7, 8, 9))
還可以用兩個元組來組成字典,利用zip函數(shù)來實現(xiàn)
a = ("agui","xuge","sun")
b = (123,5565,777)
c = dict(zip(a,b))
print(c)
輸出為: {'agui': 123, 'xuge': 5565, 'sun': 777}
?
?
通過元組的索引來創(chuàng)建字典,但是每次輸出的結(jié)果不一樣,鍵和值的順序容易發(fā)生改變
a = ("agui",232)
b = {a[0],a[1]}
print(b)
輸出為: {'agui', 232}?
元組拆包
講元組的元素拆包,并且賦值給變量id和name
id,name = (20152,"agui")
print(id)
print(name)
結(jié)果為:
20152
agui
---------------------------------------------------
for循環(huán)
迭代的對象可以是列表,字典,字符等,指的是按順序?qū)锩娴脑刈鲆恍┦虑?/p>
基本結(jié)構(gòu)為
for 變量名 in 可迭代對象
舉例 在列表里列出大于5的數(shù)字
list = [1,2,3,4,8,9,0,-3,1.9,True,False]
for target in list:
??? if target > 5:
??????? print(target)
輸出為 8,9
?
舉例,在詞典里列出成績不及格<60分的人
score = {"ming":55,"li":89,"su":99,"xu":42,"wang":32}
for mingzi,bujige in score.items():
??? if bujige<60:
??????? print(mingzi,bujige)
輸出為:
ming 55
xu 42
wang 32
?
range代表整數(shù)數(shù)列,range(1,10)代表1到9的數(shù)列? 1代表起始值,10代表結(jié)束值,結(jié)束值不在數(shù)列范圍里,所有只能表示1到9
舉例
for i range(1,10):
print(i)
結(jié)果為1-9
?
for i range(1,10,2)? 2為跳過的步長
print(i)
結(jié)果為1,3,5,7,9
-----------------------------------------------------------
while循環(huán)
基本結(jié)構(gòu)為
while 條件A
?????? 行動B
舉例:
list = ["我","喜","歡","喝","羊","肉","湯"]
while i <len(list):
??? print(list[i],end="")
??? i = i+1
輸出為:我喜歡喝羊肉湯??
如果不需要換行可以用end=""這個函數(shù)
?
輸入數(shù)字來計算平均值,輸入q結(jié)束并返回結(jié)果
i=input("請輸入要計算的數(shù)字,輸入q鍵來開始運算")
total = 0
times = 0
while i !="q":
??? total += int(i)
??? times += 1
??? i = input("請輸入要計算的數(shù)字,輸入q鍵來開始運算")
if times == 0:
?????? avr = 0
else:
??????? avr = total / times
print(int(avr))
?
這里需要注意if else和print的縮進,不要進入循環(huán)里,不然就會每次都打印出一次平均值了
--------------------------------------------------------------
格式化字符串
format
使用格式化字符串來將變量的值插入到字符串中。這可以通過在字符串中使用占位符 {} 來實現(xiàn),并使用 .format() 方法將實際的值傳遞給這些占位符
也可以在print的開頭打上f,來將變量的值
name = "agui"
year = "龍"
print("恭祝{0}新年快樂,在{1}年里事事順心,{1}年大吉!!".format(name,year))
print("恭祝{n}新年快樂,在{y}年里事事順心,{y}年大吉!!".format(n=name,y=year))
print(f"恭祝{name}新年快樂,在{year}年里事事順心,{year}年大吉!!")
?
例子2
a = 1
b = 2
print(f"和為: {a + b}")
輸出為:和為: 3
?
?
例子3
name = "agui"??????????? 這里需要用引號來定義name為str字符串
score = 21.22
print(f"{name}你好,你要查詢的成績?yōu)閧score:.2f}")???? 這里注意score后面需要接:? 不能直接用score.2f.
輸出結(jié)果為:agui你好,你要查詢的成績?yōu)?1.22
?
---------------------------------------------------------------
函數(shù)
定義函數(shù) def()??
舉例
def agui():
??? name? = "agui"
??? age = "29"
??? height = "165cm"
??? print("姓名:"+name + "\n"+ "年齡:"+age +"\n"+ "身高:"+height)
agui()
?
同時可以用def(a,b)來定義函數(shù),沒有明確的數(shù)值,但是每次調(diào)用的時候需要自定義a,b的數(shù)值
舉例:
def agui(age,height):
??? name= "agui"
??? print("姓名:"+name + "\n"+ "年齡:"+age +"\n"+ "身高:"+height)
agui("18","165")
輸出為:
姓名:agui
年齡:18
身高:165
?
自定義函數(shù)里面的值比如age,是沒有辦法被函數(shù)外直接調(diào)用的,
需要函數(shù)結(jié)尾加上reture語句,才能夠被調(diào)用
例子:
def agui(age):
??? name= "agui"
????? return age??????????
#---->這里添加return語句來返回age的值,讓print里面的變量age能夠正常運行
age=agui("18","165")
print("agui的年齡為:"+age)
?
一般情況下,定義函數(shù)時的形參和使用函數(shù)時的實參需要保持位置一直,但是可以在實際參數(shù)里面加入形參的變量名稱,就不會受到位置的限制了.比如上面的例子:
Age =agui(height=“165”,age=”18”)
也是可以正常使用函數(shù)的
?
函數(shù)的默認(rèn)值
在定義函數(shù)的時候,可以給變量加上一個默認(rèn)值,在這種情況下使用函數(shù)的時候,既可以使用函數(shù)默認(rèn)的參數(shù),也可以自定義參數(shù)
比如:
def agui(age="18"):
??? return age?
age = agui()
print("agui的年齡為:" + age)
age = agui("20")
print("agui的年齡為:" + age)
輸出為:
agui的年齡為:18
agui的年齡為:20
?
可變參數(shù)
函數(shù)可以定義接受不確定數(shù)量的參數(shù),被稱為可變參數(shù),有兩種形式,
1在參數(shù)前加 *一個星號 在函數(shù)中被組裝成一個元組
比如:
def scores(*scores):
??? total_scores = 0
??? for score in scores:
??????? total_scores +=score
??? return total_scores
print(f"agui的總分為:{(scores(100,58,92))}")
輸出為: agui的總分為:250
?
2 在參數(shù)前加** 兩個星號
表示接收任意數(shù)量的關(guān)鍵字參數(shù)。它將這些關(guān)鍵字參數(shù)打包成一個字典(dictionary),可以在函數(shù)體內(nèi)以字典的形式進行處理。這樣,你可以傳遞任意數(shù)量的關(guān)鍵字參數(shù)給函數(shù),并以鍵值對的形式進行傳遞。在函數(shù)內(nèi)部,你可以通過字典的鍵來訪問對應(yīng)的值。
比如:
def scores(**scores):
??? total_scores = 0
??? for course,score in scores.items():
??????? total_scores += score
???? ???print(f"{course}的成績?yōu)?{score}")
??? return total_scores
print(f"agui的總分為: {scores(語文=100, 數(shù)學(xué)=58, 英語=92)}")
輸出為:
語文的成績?yōu)?100
數(shù)學(xué)的成績?yōu)?58
英語的成績?yōu)?92
agui的總分為: 250
?
總結(jié):
*scores 接收任意數(shù)量的位置參數(shù),并將它們打包成元組。
**scores 接收任意數(shù)量的關(guān)鍵字參數(shù),并將它們打包成字典。
?
函數(shù)中變量的作用域
在模塊中定義的變量為:全局變量
在函數(shù)中定義的變量為:局部變量
?
在函數(shù)中使用global()可以將局部變量變?yōu)槿肿兞?不然在函數(shù)外是無法調(diào)用變量的
比如:
def agui():
??? global age
??? age = 18
??? print(f"局部變量為{age}")
agui()
print(f"全局變量為{age}")
輸出為: 局部變量為18
全局變量為18
?
函數(shù)的類型
函數(shù)在python中的數(shù)據(jù)類型為function
在一個函數(shù)中也可以引入其他函數(shù)
比如:
def agui_wcn(age):
??? print("agui今年未成年")
def agui_cn(age):
??? print("agui今年已經(jīng)成年")
def agui(year):
??? if year < 18:????????? #判斷使用的函數(shù)
??????? return agui_wcn??
??? else:
??????? return agui_cn?
years = int(input("請輸入agui年齡"))
wcn = agui(years)
wcn(years)
當(dāng)輸入18時輸出為: agui今年已經(jīng)成年
?
過濾函數(shù):
使用函數(shù)也可以對容器里的元素進行過濾,
基本格式為filter(函數(shù),容器名)
比如:
def filter_func(a):
??? return a <5
nums = [-1,-8,0,6,7,5,2,1]
result =filter(filter_func,nums) #此時為filter數(shù)據(jù)類型,需要轉(zhuǎn)換成list
print(type(result))???? #查看result的數(shù)據(jù)類型
result2 = list(result)? #將filter類型轉(zhuǎn)化為列表
print(result2)
輸出為: <class 'filter'>
[-1, -8, 0, 2, 1]
?
也可以用for語句來遍歷列表查找>5的數(shù)字,創(chuàng)建空列表,然后每次循環(huán)append符合的數(shù)字
list = list()??? #創(chuàng)建空列表
a = [-4,5,-8,0,6,8,4,2]
for i in a:
??? if i>=5:
??????? list.append(i)??? #將>5的數(shù)字添加到列表
print(list)
輸出為: [5, 6, 8]
?
?
?
映射函數(shù)(map)使用方法類似過濾函數(shù),是一個提供變換規(guī)則的函數(shù),返回變換之后的元素
基本格式為map(函數(shù),容器名):
比如:
def a(b):
??? return b * 2
nums = [-1,0,3]
result =map(a,nums)???? #使用映射函數(shù)
print(type(result))??? #查看result的數(shù)據(jù)類型
result1= list(result)?? #將result轉(zhuǎn)換為list
print(result1)
輸出為: <class 'map'>
[-2, 0, 6]
?
Lambda函數(shù)
Lambda定義的函數(shù)為匿名函數(shù),也稱為lambda函數(shù)
Lambda函數(shù)通常用于需要一個簡單函數(shù)但不想使用完整函數(shù)定義的情況。它們可以作為參數(shù)傳遞給其他函數(shù),或者用于在一行代碼中定義簡單的函數(shù)邏輯。
基本格式為:lambda 參數(shù)列表:lambda函數(shù)體
例子1:用于傳遞給其他函數(shù)
def agui(year):
??? if year < 18:
??????? return lambda age:print("未成年")
??? else:
??????? return lambda age:print("已成年")
years = int(input("請輸入agui年齡"))
wcn = agui(years)
wcn(years)
輸入為15:輸出為:未成年
?
例子2:定義簡單的函數(shù)邏輯
add = lambda x,y:x+y
result = add(2,5)
print(result)
輸出為:7
?
---------------------------------------------------------------
引入模塊
import語句
舉例:
import statistics
print(statistics.median([19,-5,36]))
?
from...import語句
form statistics import median
print(median([19,-5,36]))
?
from...import *
from statistics import *
這個語句是把模塊里的所有內(nèi)容都導(dǎo)入,使用時候都不需要加模塊名
----------------------------------------------------------------
創(chuàng)建類class
一般類名的開頭是大寫的,并且不用下劃線
基本格式為:
class 類名(父類) :
?????? 類體
父類也可以不加,如果加上父類就會繼承父類的對象屬性
?
可以用pass關(guān)鍵字來創(chuàng)建空類,相當(dāng)于用來占位,保證代碼的完整性,如果不加pass也沒有類體的情況下就會報錯.
如下
class Cat:
??? pass
?
創(chuàng)建對象:
class Cat:
??? def __init__(self):
??????? self.name = "Agui"
cat = Cat()
print(cat.name)
創(chuàng)建對象通常是通過實例化類來實現(xiàn)的,首先需要用class來創(chuàng)建類,
然后通過實例化對象
class Person:
??? # 初始化方法
??? def __init__(self, name, age):
??????? self.name = name
??????? self.age = age
??? # 創(chuàng)建方法
??? def greet(self):
??????? print(f"Hello, my name is {self.name} and I'm {self.age} years old.")
# 創(chuàng)建對象的實例
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)
# 訪問對象的屬性和方法
print(person1.name)? # 輸出: Alice
print(person2.age)? # 輸出: 30
person1.greet()? # 輸出: Hello, my name is Alice and I'm 25 years old.
person2.greet()? # 輸出: Hello, my name is Bob and I'm 30 years old.
在這個示例中
用 person1 = person(“Alice”,”25”)來創(chuàng)建對象示例
用 person1.greet() 來訪問方法,當(dāng)然也同樣適用于訪問對象 比如也可以訪問person1.name這個屬性
?
構(gòu)造方法:
構(gòu)造方法是一種特殊的方法,用于創(chuàng)建和初始化類的對象。構(gòu)造方法在對象創(chuàng)建時自動調(diào)用,并負(fù)責(zé)執(zhí)行一些必要的初始化操作,例如設(shè)置對象的初始狀態(tài)、分配內(nèi)存等。 在 Python 中,構(gòu)造方法的名稱固定為 __init__。它位于類的定義中,并以 self 作為第一個參數(shù),用于引用正在創(chuàng)建的對象本身。除了 self 參數(shù)外,構(gòu)造方法還可以接受其他參數(shù),用于初始化對象的屬性。
例子如下:
class Person:
??? def __init__(self, name, age):?? #構(gòu)造方法必須是__init__的名稱
??????? self.name = name
??????? self.age = age
# 創(chuàng)建 Person 對象
person = Person("Alice", 25)? #基于位置來傳遞參數(shù)
# 訪問對象的屬性
print(person.name)? # 輸出: Alice
print(person.age)? # 輸出: 25
?
?
實例方法
實例方法是定義在類中的方法,用于操作和訪問類的實例(對象)的數(shù)據(jù)。實例方法必須在類實例化后才能被調(diào)用,且在調(diào)用時會自動將實例本身作為第一個參數(shù)傳遞,通常被命名為 self。
比如:def talk(self): 此處定義方法的用法和定義函數(shù)相似,區(qū)別是:??
一,需要寫在class里,前面需要有縮進來表示這個方法屬于該類,??
二,第一個參數(shù)為self,用來表示對象自身
例子:
class human:
??? def __init__(self,name):
??????? self.name = name
??? def walk(self):
??????? print(f"{self.name} is walking.")
??? def talk(self,sound):
??????? print(f"{self.name} says: {sound}")
man = human("xiaoming")
man.walk()?????? #此處由于walk方法中沒有其他參數(shù),所以可以留空
man.talk(2)????? #這次由于talk方法中有sound參數(shù),所以需要填寫
輸出為: xiaoming is walking.
xiaoming says: 2
?
類變量
類變量是屬于類的變量,不屬于單個對象.
比如:
class man:
??? sex = "男性"
??? def __init__(self,name,age):
??????? self.name = name
??????? self.age = age
a = man("xiaoming",18)
print(f"{a.name}是一個{a.age}歲的{a.sex}")?? #a.sex也可以寫成Man.sex
輸出為: xiaoming是一個18歲的男性
在這里性別就是類的變量,對象可以進行調(diào)用,
如果此時在print前面加上 a.sex = “女性”,那么會優(yōu)先調(diào)用”女性”的這個值,如果想調(diào)用之前的變量值可以用類變量Man.sex來實現(xiàn)
?
類方法
在函數(shù)上行加入 @classmethod這個裝飾器
比如
class Rate:
??? rate = 0.6???? #定義類變量
??? def __init__(self,price):
??????? self.price = price
??? @classmethod????? #類方法裝飾器
??? def a(cls,amount):???? #定義類方法
??????? return cls.rate * amount?? #返回計算結(jié)果
c =Rate.a(500)? #通過rate這個類來調(diào)用a這個類方法
print(c)
輸出為:300
對于類方法的第一個參數(shù),通常是cls,而不是之前的self
?
封裝性
封裝是面向?qū)ο缶幊讨械囊粋€重要概念,它指的是將數(shù)據(jù)和操作數(shù)據(jù)的方法包裝在一個對象中,以實現(xiàn)數(shù)據(jù)的隱藏和保護。封裝通過將數(shù)據(jù)設(shè)置為私有屬性(private attribute)并提供公共接口(public interface)來實現(xiàn)。
?
封裝的主要目的是隱藏對象內(nèi)部的實現(xiàn)細(xì)節(jié),使得對象的使用者只需要關(guān)注對象提供的公共接口,而不需要了解對象的具體實現(xiàn)細(xì)節(jié)。這樣可以提高代碼的可維護性、可擴展性和安全性。
舉個例子:在用網(wǎng)線的時候,只需要將伸出來的線頭插入設(shè)備,就可以正常的使用了,并不需要去了解網(wǎng)線內(nèi)部結(jié)構(gòu).
?
私有變量
為了放置外部調(diào)用者隨意存取類的內(nèi)部結(jié)構(gòu)(成員變量),內(nèi)部數(shù)據(jù)(成員變量)會被封裝為:私有變量
?
私有變量,在變量前加上雙下劃線 __
示例如下:
class Rate:
??? __rate = 0.6???? #定義類變量
??? def __init__(self,name,price):
??????? self.name = name????? #創(chuàng)建并初始化公有實例變量name
??????? self.__price = price? #創(chuàng)建并初始化私有實例變量__price
??? def prin(self):??????? #公有方法用于訪問私有變量
??????? print(f"{self.name}的利率是{self.__rate},價格為:{self.__price}")
a = Rate("手套",50)
a.prin()
print(f"商品名:{a.name}")??? #可以正常訪問,輸出結(jié)果為"手套"
print(f"商品價格:{a.price}")???? #price為私有變量,所以無法訪問會報錯
print(f"商品利潤率為:{a.__rate}")?? #rate為私有類變量,所有無法訪問會報錯
總結(jié):私有變量是沒辦法被外部直接調(diào)用或者讀取的,需要利用公有的方法來訪問,
但是公有變量是可以直接用來訪問的
如果直接在外部調(diào)用私有變量會造成AttributeError
?
私有方法
私有方法的封裝是類似的,在方法名前加上雙下劃線__ 就會將公有方法變?yōu)樗接蟹椒?/p>
例子如下:
class Rate:
??? __rate = 0.6???? #定義類變量
??? def __init__(self,name,price):
??????? self.name = name????? #創(chuàng)建并初始化公有實例變量name
??????? self.__price = price? #創(chuàng)建并初始化私有實例變量__price
??? def __prin(self):??????? #私有方法用于訪問私有變量
??????? print(f"{self.name}的利率是{self.__rate},價格為:{self.__price}")
??? def get_prin(self):?? #創(chuàng)建公有方法用來訪問私有方法__prin
??????? return self.__prin()
a = Rate("手套",50)
a.get_prin()? #此處用get_prin的公有方法來訪問私有方法__prin
????????????? #如果直接寫成a.prin()就會attributeError報錯
輸出為: 手套的利率是0.6,價格為:50
總結(jié):私有方法和私有變量類似,也是無法直接進行外部訪問的,需要借助其他的類方法進行訪問和使用.如果直接調(diào)用的話,就會和私有變量一樣,出現(xiàn)AttributeError的錯誤
?
使用屬性(封裝)
屬性(property)是一種特殊的方法,它可以讓我們使用類似于訪問對象屬性的語法來訪問和修改對象的數(shù)據(jù),同時可以在訪問和修改時執(zhí)行特定的邏輯。屬性提供了一種更優(yōu)雅和簡潔的方式來控制對象的狀態(tài)和行為。
?
在Python中,可以使用@property裝飾器定義屬性。屬性由getter方法和可選的setter方法組成,分別用于獲取和設(shè)置屬性的值。getter方法使用@property裝飾器修飾,setter方法使用@property裝飾器的.setter裝飾器修飾。
基本格式為:
@property?? (get裝飾器)?
def a(self):
?????? return self.__a
@a.setter???? (set裝飾器)
def a(self,a)
?????? self.__a = a
?
下面用例子演示:
還是以手套為例
class Rate:
??? def __init__(self,name,price):
??????? self.name = name
??????? self.__price = price
??? @property?? #設(shè)置price的取值方法,即get
??? def price(self):
?????? return self.__price
??? @price.setter
??? def price(self,price):
??????? self.__price = price
a = Rate("手套",50)
print(f"手套的價格為{a.price}")??? #這里是取值get
a.price = 80?? #a.price放在=的左邊就是賦值set
print(f"手套的新價格為:{a.price}")? #由于重新被賦值,新的價格為80
輸出為:
手套的價格為50
手套的新價格為:80
?
類的繼承
繼承性也是面向?qū)ο笞钪匾幕咎卣髦?在現(xiàn)實世界中繼承關(guān)系無處不在
例如,貓與哺乳動物之間的關(guān)系,貓是哺乳動物,具有哺乳動物的特征,比如四條腿,兩只眼,一個鼻子等,行為上比如走路,會尿尿等
此時可以將”哺乳動物”成為”貓”的父類.”貓”就是”哺乳動物”的子類,子類擁有父類的全部數(shù)據(jù)和行為,即數(shù)據(jù)和方法
子類的的調(diào)用屬性,優(yōu)先子類的方法,如果沒有的話會調(diào)用父類同名的方法
如果給子類寫了init方法,創(chuàng)建了子類實例時,會優(yōu)先調(diào)用子類的構(gòu)造函數(shù),導(dǎo)致實例只有某種屬性,
這是需要用到super(),用法是----> super().__init__(name,age)
?
class Mammal:
??? def __init__(self,name):
??????? self.name = name
??? def walk(self):
??????? return f"{self.name},今年{self.age}歲了,往前跑了兩步"
class Cat(Mammal):
??? def __init__(self,name,age):
??????? super().__init__(name) #這里由于子類定義了age屬性,要用super()來調(diào)用父類的參數(shù)信息
??????? self.age = age
cat1 = Cat("agui",2)
print(cat1.walk())
輸出為: agui,今年2歲了,往前跑了兩步
?
比如walk的這個方法,子類中是沒有的,但是由于Mammal是Cat的父類,所以方法也被繼承到了子類中.
?
多繼承
多繼承是指一個類可以繼承自多個父類的特性和行為。在Python中,多繼承是一種面向?qū)ο缶幊痰奶匦?,允許一個類繼承自多個父類,并繼承它們的屬性和方法。
比如class Cat3(Cat1,Cat2):
如果兩個父類都有同樣的實例變量,那么子類會優(yōu)先繼承第一個父類(Cat1)
如果父類擁有獨特的成員變量,那么子類只繼承擁有變量的父類的變量
舉例如下:
class Cat1:
??? def __init__(self,name):
??????? self.name =name
??? def walk(self):
??????? return f"名字叫{self.name}的Cat1跑了起來"
class Cat2:
??? def __init__(self,name):
??????? self.name = name
??? def walk(self):
??????? return f"名字叫{self.name}的Cat2跑了起來"
??? def climb(self):
??????? return f"名字叫{self.name}的Cat2爬到了樹上"
class Cat3(Cat1,Cat2):
??? def __init__(self,name):
??????? super().__init__(name)
a = Cat3("agui")
print(a.walk())? #由于Cat1和2都會walk,所以Cat3會繼承Cat1的walk
print(a.climb())? #由于只有Cat2會climb,所以Cat3會繼承Cat2的climb
輸出為:
名字叫agui的Cat1跑了起來
名字叫agui的Cat2爬到了樹上
?
方法重寫
如果子類中也定義了和父類同樣的方法,那么會優(yōu)先調(diào)用子類的方法
例子如下:
class Cat1:
??? def __init__(self,name):
??????? self.name =name
??? def walk(self):
??????? return f"名字叫{self.name}的Cat1跑了起來"
class Cat2:
??? def __init__(self,name):
??????? self.name = name
??? def walk(self):
??????? return f"名字叫{self.name}的Cat2跑了起來"
??? def climb(self):
??????? return f"名字叫{self.name}的Cat2爬到了樹上"
class Cat3(Cat1,Cat2):
??? def __init__(self,name):
??????? super().__init__(name)
??? def climb(self):
??????? return f"名字叫{self.name}的Cat3爬到了樹上"
a = Cat3("agui")
print(a.climb())
由于父類Cat2和子類Cat3都擁有climb的方法,所有當(dāng)子類Cat3繼承父類Cat2時,會優(yōu)先調(diào)用Cat3的climb方法
輸出為: 名字叫agui的Cat3爬到了樹上
?
多態(tài)性(重點)
“多態(tài)”指的是對象可以表現(xiàn)出多種形態(tài)
它允許不同類的對象對同一消息做出不同的響應(yīng)。具體來說,多態(tài)性指的是通過使用父類的引用變量來調(diào)用子類的方法,根據(jù)實際對象的類型來確定調(diào)用的方法。這樣可以實現(xiàn)代碼的靈活性和可擴展性。
?
下面的例子通過定義了狗,貓和鴨子的sound,來實現(xiàn)不同動物的sound的區(qū)別
?
例子1:
class Animal:
??? def sound(self):
??????? pass
class Dog(Animal):
??? def sound(self):
??????? print("汪汪汪")
class Cat(Animal):
??? def sound(self):
??????? print("喵喵喵")
class Duck(Animal):
??? def sound(self):
??????? print("嘎嘎嘎")
animals =[Dog(),Cat(),Duck()]
for animal in animals:
??? animal.sound()
輸出為: 汪汪汪
喵喵喵
嘎嘎嘎
?
例子2:
class Shape:
??? def area(self):
??????? pass
class Rectangle(Shape):
??? def __init__(self, width, height):
??????? self.width = width
??????? self.height = height
??? def area(self):
??????? return self.width * self.height
class Circle(Shape):
??? def __init__(self, radius):
??????? self.radius = radius
??? def area(self):
??????? return 3.14 * self.radius * self.radius
shapes = [Rectangle(4, 5), Circle(3), Rectangle(2, 7)]
for shape in shapes:
??? print("面積:", shape.area())
輸出為:
面積: 20
面積: 28.259999999999998
面積: 14
總結(jié):
多態(tài)一定是出現(xiàn)在繼承的情況下,沒有繼承就沒有多態(tài)
通過多態(tài)性,我們可以編寫通用的代碼,處理不同類型的對象,而不需要針對每個具體類編寫特定的代碼。這樣可以提高代碼的復(fù)用性和可維護性。
?
繼承與多態(tài)
多態(tài)一定是出現(xiàn)在繼承的情況下
在多個子類繼承了父類,并且重寫了父類的方法后,這些子類所創(chuàng)建的對象之間就是多態(tài)的,
比如上述的例子中,animals同時包含了狗,貓,鴨子,但是每種動物的叫聲都是不同的,所采用的sound方式是不同的.
?
鴨子類型測試與多態(tài)
鴨子類型(Duck typing)是一種動態(tài)類型的概念,它關(guān)注的是對象的行為而不是類型本身。在鴨子類型中,一個對象的可用性不是基于它的類或繼承關(guān)系,而是基于它是否具有特定的方法、屬性或行為。
?
例子如下:
class Animal:
??? def quack(self):
??????? print("有東西在叫!")
class Duck(Animal):
??? def quack(self):
??????? print("鴨子在嘎嘎叫")
class Human(Animal):
??? def quack(self):
??????? print("人在模仿鴨子嘎嘎叫")
def check(obj):
??? obj.quack()
check(Duck())
check(Human())
輸出為: 鴨子在嘎嘎叫
人在模仿鴨子嘎嘎叫”
在上面的例子中,定義了一個 Duck 類和一個 Human 類,它們都有相同的方法 quack。雖然他們的類別不同,但他們的行為類似于鴨子,因此可以通過鴨子類型的方式傳遞給函數(shù) check,并調(diào)用相同的方法。
鴨子類型的核心思想是通過對象的行為來決定其可用性,而不是依賴于特定的類型或繼承關(guān)系。這種靈活性使得代碼更加通用和可復(fù)用,可以處理各種具有相似行為的對象,而無需顯式地指定它們的類型。
?
異常(Exception)
異常(Exception)是在程序執(zhí)行過程中出現(xiàn)的錯誤或異常情況。當(dāng)發(fā)生異常時,程序會中斷當(dāng)前的執(zhí)行流程,并跳轉(zhuǎn)到異常處理代碼塊,以便進行錯誤處理、恢復(fù)或終止程序運行。
?
在Python中,異常是通過拋出(raise)和捕獲(catch)來處理的。當(dāng)發(fā)生異常時,可以使用try-except語句來捕獲異常并進行相應(yīng)的處理。try塊中包含可能會引發(fā)異常的代碼,而except塊則包含異常處理的代碼。
?
除零異常
當(dāng)在數(shù)學(xué)計算時,分母為0時會出現(xiàn)的錯誤就是除零異常
例子:
i = input("請輸出分母")
n = 1
result = n/int(i)
print(f"{n}除以{i}的結(jié)果為:{result}")
當(dāng)輸入為0時,報錯ZeroDivisionError: division by zero
?
可以加入一個判斷語句來避免此錯誤
i = input("請輸出整數(shù)分母")
n = 1
if i == "0":??? #判斷輸入的數(shù)字是否為0
??? print("請輸入不為零的整數(shù)")? #如果結(jié)果為零,則打印請輸入不為零的整數(shù)
else:
??? result = n/int(i)
??? print(f"{n}除以{i}的結(jié)果為:{result}")
?
捕獲異常
try-except語句的使用
基本格式為:
try:
?????? <可能會引發(fā)異常的語句>
except異常類型 as 變量名:?
?????? <處理異常>
異常類型 as 變量名 都可以省略,省略時會捕獲所有的異常類型并且不會儲存變量
上面的例子可以改寫成:
i = input("請輸出分母")
n = 1
try:
??? result = n/int(i)
??? print(f"{n}除以{i}的結(jié)果為:{result}")
except ZeroDivisionError as b:
??? print(f"不能除以0,出現(xiàn)了錯誤")
當(dāng)輸入為0時輸出: 不能除以0,出現(xiàn)了錯誤division by zero
?
?
?
?
多個except代碼塊
基本格式為:
try:
?????? <可能會引發(fā)異常的語句>
except異常類型1 as 變量名:?
?????? <處理異常>
except異常類型2 as 變量名:?
…
except: ???????????????????
?????? <處理異常>??
#省略異常類型的except代碼塊通常放在最后,來捕獲沒有匹配的異常類型,用來兜底
還是用剛才的例子:
i = input("請輸出分母")
n = 1
try:
??? result = n/int(i)
??? print(f"{n}除以{i}的結(jié)果為:{result}")
except ZeroDivisionError as b:
??? print(f"不能除以0,出現(xiàn)了錯誤")
except ValueError as b:
??? print(f"輸入的是無效數(shù)字,出現(xiàn)了錯誤")
這里加入了另一個except代碼來捕獲輸入字符類型的錯誤
當(dāng)輸入字母的時候,會輸出: 輸入的是無效數(shù)字,出現(xiàn)了錯誤invalid literal for int() with base 10: 'a'
?
多重異常捕獲
也可以將except的異常類型放在小括號()中,并且用,逗號分割開
這樣只需一個except代碼就可以捕獲多個異常了
例子:
i = input("請輸出分母")
n = 1
try:
??? result = n/int(i)
??? print(f"{n}除以{i}的結(jié)果為:{result}")
except (ZeroDivisionError,ValueError) as b:
??? print(f"輸入的數(shù)字有誤,出現(xiàn)了錯誤")
此時,無論輸入的是0還是非法字符,都會輸出錯誤類型
?
try-except語句的嵌套
多重異常捕獲和try-except語句塊嵌套的區(qū)別在于異常處理的方式和代碼結(jié)構(gòu)的清晰度。
多重異常捕獲是指在單個try-except語句塊中捕獲多個不同類型的異常。使用多個except子句來分別處理不同的異常類型。這樣可以在單個try塊中處理多個可能的異常情況,提高代碼的簡潔性。
?
try-except語句嵌套是指在一個try代碼塊中嵌套另一個try-except語句塊。內(nèi)層的try-except塊可以用于處理更具體的異常情況,而外層的try-except塊可以用于處理更一般的異常情況。這種嵌套結(jié)構(gòu)可以提供更精細(xì)的異常處理邏輯。
例子:
i = input("請輸出分母")
n = 1
try:
??? i = int(i)
??? try:
??????? result = n / i
??????? print(f"{n}除以{i}的結(jié)果為:{result}")
??? except ZeroDivisionError as b:
??????? print(f"輸入的數(shù)字有誤,出現(xiàn)了錯誤")
except ValueError as b:
??? print(f"輸入的是無效數(shù)字,出現(xiàn)了錯誤")
?
finally代碼塊
有時在try-except語句中會占用一些系統(tǒng)資源,可以使用finally代碼塊來釋放資源
例子:
i = input("請輸出分母")
n = 1
try:
??? result = n/int(i)
??? print(f"{n}除以{i}的結(jié)果為:{result}")
except ZeroDivisionError as b:
??? print(f"不能除以0,出現(xiàn)了錯誤")
except ValueError as b:
??? print(f"輸入的是無效數(shù)字,出現(xiàn)了錯誤")
finally:
print("釋放資源,無論是否出現(xiàn)異常,都是打印此段話")
在這個例子中,無論用戶輸入的是有效整數(shù)還是非整數(shù),以及是否出現(xiàn)除零錯誤,最后的 print 語句都會被執(zhí)行。finally 塊通常用于清理資源、釋放打開的文件、關(guān)閉數(shù)據(jù)庫連接等必須執(zhí)行的操作。
?
自定義異常類
class CustomException(Exception):
??? def __init__(self,message):
??????? super().__init__(message)
?
手動引發(fā)異常
利用自己創(chuàng)建的異常類來使捕獲的異常轉(zhuǎn)化為自定義的異常
例子:
class CustomException(Exception):
??? def __init__(self,message):
??????? super().__init__(message)
i = input("請輸出分母")
n = 1
try:
??? result = n/int(i)
??? print(f"{n}除以{i}的結(jié)果為:{result}")
except ZeroDivisionError as b:
??? raise CustomException("不等除以0")
except ValueError as b:
??? raise CustomException("無效數(shù)字")
輸出:raise CustomException("不等除以0")
__main__.CustomException: 不等除以0
?
----------------------------------------------
?
文件操作
??? 讀取文件
read 返回全部文件內(nèi)容的字符串
例子:
f = open("./data.txt","r",encoding="utf-8")???? r為讀 w為寫 a為附加內(nèi)容 encoding是編碼
content = f.read()
print(content)
f.close()??????????????? #最后運行close來釋放內(nèi)存
?
或者用
with open("./data.txt","r",encoding="utf-8") as f:??? #用with...as 這樣的格式就不需要結(jié)尾用close關(guān)閉了,會自動關(guān)閉
content = f.read()
print(content)
?
readline 返回一行文件內(nèi)容的字符串
例子:
with open("./data.txt","r",encoding="utf-8") as f:
??? print(f.readline())
注意縮進一定要有,不然會報錯
?
readlines 返回全部文件內(nèi)容組成的列表
例子:
with open("./data.txt","r",encoding="utf-8") as f:
??? lines = f.readlines()
??? for line in lines:
??????? print(line)
readlines一般結(jié)合for循環(huán)使用,如果不想要換行符,可以用print(line.strip())來實現(xiàn),就不會出現(xiàn)換行了
?
===============
寫入文件
with open("./data.txt","w",encoding = "utf-8") as f:????? 如果文件不存在,會自動創(chuàng)建
?
insert插入
可以用
a.insert(2,”x”)來插入元素
比如:
a = ["a","b","c"]
a.insert(2,"X")
print(a)
” ['a', 'b', 'X', 'c']
?
替換元素
可以使用索引來替換掉相應(yīng)位置的元素
a = ["a", "b", "c"]
a[1] = "X"
print(a)
['a', 'X', 'c']
?
?
雜項(不容易被分類的內(nèi)容放到了這里)
來記錄一些名詞和概念,已經(jīng)一些零散的使用方法
創(chuàng)建內(nèi)容的方式
空集合set(),??? 或者a ={1,3,4,5}
空列表list()???? 或者 a = [1,2,3,4]
空元組tuple()?? 或者 a = (1,2,3,4)
空字典dict()??? 或者 a = {"a”:1,”b”:2}
?
?
在 Python 中,如果函數(shù)沒有明確使用 return 語句返回一個值,或者只是使用 return 語句而沒有跟隨任何值,那么函數(shù)會默認(rèn)返回 None。這就是為什么在你提供的例子中,如果去掉 return 語句,result 變量會顯示 None。
讓我們看一個簡單的示例來說明這一點:
def my_function():
??? print("Hello")
result = my_function()
print(result)
輸出為:
Hello
None
?
在上述示例中,函數(shù) my_function 只包含了一個 print 語句,而沒有使用 return 語句返回任何值。當(dāng)調(diào)用 my_function() 時,會在控制臺打印 "Hello",但由于沒有返回值,變量 result 的值為 None。 因此,在你提供的例子中,如果去掉 return 語句,函數(shù) add_numbers 將會默認(rèn)返回 None,導(dǎo)致 result 的值為 None。 如果你希望函數(shù)返回一個特定的值,在函數(shù)內(nèi)部使用 return 語句來顯式指定返回值即可。如果不需要返回值,可以省略 return 語句或者只使用 return 關(guān)鍵字,不跟隨任何值。
?
?
math模塊的函數(shù)與說明
?