Python基礎(chǔ)常識(shí)
python 區(qū)分大小寫(xiě) Andy != andy
print("\r", end="")
end="" 關(guān)閉print的自動(dòng)\n "\r" 返回行首打印
"\r" end=""
可以實(shí)現(xiàn)在shell中始終在一行的開(kāi)頭打印
temp = """string"""
實(shí)際上是一個(gè)可以換行的字符串 可以讓變量來(lái)保存 如果在類(lèi)或者函數(shù)里就是類(lèi)和函數(shù)的說(shuō)明文檔
input("請(qǐng)輸入:")
接收鍵盤(pán)輸入的信息 返回字符串
type(對(duì)象)
查看數(shù)據(jù)類(lèi)型
id(對(duì)象)
查看對(duì)象的引用地址以10進(jìn)制
dir(對(duì)象)
查看對(duì)象的所有屬性和方法 包括繼承的
代碼太長(zhǎng)可以在需要換行的地方輸入\然后換行或者使用()
TODO(作者)
標(biāo)簽 提示還沒(méi)開(kāi)發(fā)完成的功能
pass
占位符保證程序結(jié)構(gòu)正確
while True:
循環(huán)入口 當(dāng)while后的值為邏輯真時(shí) 進(jìn)入無(wú)限循環(huán)
+=
可以合并列表 元組 字符串 針對(duì)列表的+=
實(shí)際上是調(diào)用了extend
方法 所以在函數(shù)內(nèi)需要注意(可變數(shù)據(jù)類(lèi)型)
變量保存著程序在自身內(nèi)存空間中為數(shù)據(jù)提供的空間的引用
關(guān)鍵字就是python內(nèi)置的功能 特點(diǎn)是后面不跟括號(hào) 直接使用(區(qū)別于property)
函數(shù)就是封裝好的功能 特點(diǎn)是后面跟一個(gè)括號(hào)
方法就是針對(duì)面向?qū)ο蟮暮瘮?shù) 對(duì)象.函數(shù)()
cpython37.pyc
結(jié)尾的文件是python解釋器編譯過(guò)的代碼 以二進(jìn)制的形式儲(chǔ)存在電腦 目的是加快代碼運(yùn)行速度
代碼的結(jié)構(gòu) shebang
==>import
==>定義的常量
==>定義的函數(shù)
==>代碼
變量與常量
用來(lái)存儲(chǔ)數(shù)值時(shí)變量
變化的量 常量
不變化的量
變量
的命名所有字母小寫(xiě)用下劃線連接單詞
常量
的命名所有字符大寫(xiě)用下劃線連接單詞
不要在代碼中直接出現(xiàn)數(shù)字而應(yīng)該使用常量
數(shù)據(jù)類(lèi)型
數(shù)字型 int
float
bool
complex
布爾屬于數(shù)字型
非數(shù)字型 str
list
tuple
dict
數(shù)據(jù)類(lèi)型轉(zhuǎn)換
int(str|float)
轉(zhuǎn)換小數(shù)向下取整 無(wú)法轉(zhuǎn)換帶.
字符串類(lèi)型小數(shù) 可以 int(float(str))
float(str|int)
bool(0即假 值為空即假 None即假)
str(num)
tuple(list)
list(tuple)
None
表示空對(duì)象 什么都沒(méi)有
值為空不是None
是空數(shù)據(jù)的對(duì)象
拼接字符串
str * num
str + str
list * num
list + list
tuple *num
tuple + tuple
list + tuple
不能交叉合并
格式化字符串
%s
字符串
%d
十進(jìn)制數(shù)字
%x
十六進(jìn)制數(shù)字
%f
浮點(diǎn)型
%05.2f
保留2位小數(shù)并且保證整體寬度為5不足的以0占位 03.00
格式化字符串輸出%
使用%%
格式化字符串的參數(shù)
本質(zhì)上就是一個(gè)元組 可以用元組替換 print("%s年齡是%d身高是%.2f" % (tuple))
轉(zhuǎn)義字符
\n
換行
\r
回到行首
\t
\v
制表符
\u
轉(zhuǎn)義unicode字符串 \u00b2
分支語(yǔ)句
例1
if xxx: (判斷的是邏輯真假)
xxx
else:
xxx
例2
if xxx:
xxx
elif xxx:
xxx
else:
xxx
IF嵌套
例3
if xxx:
xxx
if xxx:
xxx
else:
xxx
else:
xxx
三元表達(dá)式
方法一: 為真時(shí)的結(jié)果 if 判定條件 else 為假時(shí)的結(jié)果
d = b if a else c #如果a為真糟港,結(jié)果是b矿卑,否則結(jié)果是c
print('方法一輸出結(jié)果:' + d)
方法二: 判定條件 and 為真時(shí)的結(jié)果 or 為假時(shí)的結(jié)果
d = a and b or c #如果a為真比藻,結(jié)果是b寄雀,否則結(jié)果是c
print('方法二輸出結(jié)果:' + d)
以上兩種方法方法等同于if ... else ...
if a:
d = b
else:
d = c
print('if語(yǔ)句的輸出結(jié)果:' + d)
循環(huán)語(yǔ)句
例1
i = 0
while i (判斷) xxx: (判斷的是邏輯真假)
xxx
i += 1 # 設(shè)置循環(huán)換出口 在循環(huán)體外部設(shè)置計(jì)數(shù)器在內(nèi)部每次迭代為計(jì)數(shù)器+1
例2
i = 0
while i (判斷) xxx:
if i (判斷) m:
xxx
break # 當(dāng)程序滿足某個(gè)條件 直接結(jié)束本層循環(huán) 不執(zhí)行本層循環(huán)體的后續(xù)代碼
i += 1
例3
i = 0
while i (判斷) xxx:
if i (判斷) m:
xxx
i += 1
continue # 當(dāng)程序滿足某個(gè)條件 重新循環(huán)本層循環(huán)體的下一個(gè)迭代 不執(zhí)行本層循環(huán)體的后續(xù)代碼
xxx
i += 1
WHILE嵌套
例4
i = 0
while i (判斷) xxx:
m = 0
while m (判斷) i:
xxx
m += 1
break # 只影響當(dāng)前的循環(huán)體 不影響上一層的循環(huán)體
xxx
i += 1
break
continue
只影響當(dāng)前的循環(huán)體 不影響上一層的循環(huán)體
迭代遍歷
for num in list():
實(shí)際上執(zhí)行l(wèi)ist對(duì)象的__iter__
方法如果有此方法說(shuō)明對(duì)象是一個(gè)可迭代對(duì)象如果沒(méi)有說(shuō)明無(wú)法迭代
__iter__
會(huì)返回一個(gè)對(duì)象如果這個(gè)對(duì)象有__next__
方法實(shí)現(xiàn)for循環(huán)
每循環(huán)依次取__next__
的返回值給num
可迭代對(duì)象如果沒(méi)有通過(guò)iter
返回一個(gè)具有next
方法實(shí)現(xiàn)的對(duì)象 那么無(wú)法實(shí)現(xiàn)迭代
完整的FOR循環(huán)
for i in 集合:
print(i)
if i == x:
break
else:
print(break后不執(zhí)行)
print(結(jié)束遍歷)
遍歷結(jié)束后執(zhí)行else
后的代碼但如果break
則不會(huì)執(zhí)行
函數(shù)
函數(shù)的定義
def 函數(shù)名():
"""注釋 define 上要要留兩行空行pycharm中cltr + q 可以查看注釋"""
函數(shù)的封裝
文件保存的名字fun_file
是模塊的名字
函數(shù)名是模塊的方法 fun_file.方法()
不主動(dòng)調(diào)用 封裝的內(nèi)容不會(huì)執(zhí)行
函數(shù)的調(diào)用
import fun_file
用來(lái)加載定義的模塊
fun_file.函數(shù)()
用來(lái)調(diào)用模塊的方法
函數(shù)的參數(shù)
def 函數(shù)名(形參1, 形參2, …):
result = 形參1*形參2
return result
i = 函數(shù)名(實(shí)參1, 實(shí)參2, …)
print(i)
return
把結(jié)果返回給外部調(diào)用函數(shù)的函數(shù)名
return
可以結(jié)束函數(shù)和方法 下方的代碼不會(huì)被執(zhí)行
return
也可以終止循環(huán)體 并且不管多少層都直接終止
返回時(shí): 可使用元組來(lái)返回多個(gè)結(jié)果 return (結(jié)果1, 結(jié)果2, 結(jié)果3)
可以省略括號(hào)
接收時(shí): 返回的是元組 使用多個(gè)變量接收 變量1, 變量2, 變量3 = 函數(shù)()
(實(shí)際是一個(gè)元組 拆包)
函數(shù)的遞歸
在函數(shù)內(nèi)部 調(diào)用函數(shù)自己 叫做函數(shù)的遞歸如果不指定出口會(huì)死循環(huán)
函數(shù)的遞歸求1到100的累加結(jié)果
def sum_num(num):
if num == 1:
return 1
temp = sum_num(num-1)
return num + temp
sum_ = sum_num(100)
print(sum_)
eval()函數(shù)
eval()
函數(shù)會(huì)計(jì)算字符串中的表達(dá)式
并返回結(jié)果
不要濫用eval()
轉(zhuǎn)換input
的內(nèi)容
enumerate()函數(shù)
可以對(duì)list
tuple
str
有序合集枚舉 無(wú)法對(duì)dict
枚舉
enumerate(seq, start=num)
返回的是一個(gè)對(duì)象 也可以通過(guò)start=num
指定序號(hào)起始數(shù)字
每個(gè)元組內(nèi)容為 (0, H), (1, e), (2, l)
通常配合遍歷使用
list = [1, 2, 3, 4, 5]
for i, num in enumerate(list):
print(i) # 序號(hào)
print(num) # 元素
列表 list
定義列表
list = ["張三"蛛蒙, "李四"倔撞, "王五"]
列表的方法
取值 list[下標(biāo)]
下標(biāo)也就是索引
從0開(kāi)始
取索引 list.index("char")
char的索引是幾就返回幾
list[index] = "char"
把下標(biāo)index的數(shù)據(jù)修改為char
list.append("char")
在列表末尾追加一個(gè)數(shù)據(jù) list.append(list2)
是追加一個(gè)元素會(huì)顯示為[1, 2, 3, [1, 2, 3]]
list.insert(0, "char")
向索引0的前面插入一個(gè)char
list.extend(list_2)
把列表2合并到list末尾 是合并一個(gè)列表會(huì)顯示為[1, 2, 3, 1, 2, 3]
del list
刪除列表
list.remove("char")
從列表中刪除這個(gè)數(shù)據(jù)
list.pop(index)
刪除這個(gè)索引下的數(shù)據(jù)
list.clear()
清空列表
list.pop()
刪除最后一個(gè)索引的數(shù)據(jù)
len(list)
顯示列表長(zhǎng)度
list.count("char")
查看某個(gè)數(shù)據(jù)在列表中出現(xiàn)的次數(shù)
list.sort()
升序排列
list.sort(reverse=True)
降序排列
list.reverse()
逆序 顛倒排列
元組 tuple
定義元組
tuple = ()
空元組
tuple = (char,)
單元素元組
元組的方法
取值 tuple[index]
取索引 tuple.index("char")
查詢(xún)char的索引下標(biāo)
tuple.count("char")
統(tǒng)計(jì)char在元組里出現(xiàn)的次數(shù)
len(tuple)
查詢(xún)?cè)M的長(zhǎng)度
字典 dict
字典是以 key: value
鍵值對(duì)對(duì)應(yīng) 特點(diǎn)是無(wú)序 列表元組有序
定義字典
dict = {"name": "Lee", "age": 18, "height": 1.75}
key
必須唯一 value
不必唯一
字典的方法
取值 dict["key"]
修改 dict["key"] = "value"
增加 dict["key"] = "value"
當(dāng)key
不存在表示添加鍵值對(duì)
刪除鍵值對(duì) dict.pop("key")
清空 dict.clear()
合并 dict.update(dict2)
刪除字典 del dict
len(dict)
有多少組鍵值
dict.keys()
顯示所有鍵 以列表形式
dict.values()
顯示所有值 以列表方式
dict.items()
顯示所有鍵值對(duì) 以列表方式
集合 set
在 Python 中,集合分為兩類(lèi):
-
set
可變集合 可以原地修改 是 unhashable(不可哈希)的 -
frozenset
不可變集合 顧名被“凍結(jié)”的集合 不能原地修改 是 hashable(可哈希)的
集合(set)
是一個(gè)無(wú)序
的不重復(fù)
元素的序列并且是不可變類(lèi)型
集合不支持索引
可以使用大括號(hào){ }
或者set()
函數(shù)創(chuàng)建集合
創(chuàng)建一個(gè)空集合
必須用 set()
而不是 { } 因?yàn)?{ } 是用來(lái)創(chuàng)建一個(gè)空字典
推導(dǎo)式
推導(dǎo)式comprehensions
(又稱(chēng)解析式) 推導(dǎo)式是可以從一個(gè)數(shù)據(jù)序列構(gòu)建另一個(gè)新的數(shù)據(jù)序列的結(jié)構(gòu)體 共有三種推導(dǎo)式
- 列表(list)推導(dǎo)式
- 字典(dict)推導(dǎo)式
- 集合(set)推導(dǎo)式
推到式的格式: [表達(dá)式 for 變量 in 列表]
或者 [表達(dá)式 for 變量 in 列表 if 條件]
推導(dǎo)式不僅讓代碼更簡(jiǎn)潔執(zhí)行速度也更快
列表推導(dǎo)式
lst = [i for i in range(10)] # 生成列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lst = [i*2 for i in range(10) if i >= 5] # 生成當(dāng)i大于5時(shí)i平方的列表[25, 36, 49, 64, 81]
type(lst) # list
元組(生成器)推導(dǎo)式
gen = (i for i in range(10)) # 生成生成器通過(guò)next()函數(shù)或者gen.__next__()方法取值
type(gen) # generator
集合推導(dǎo)式
lst = [ 9, 1, 1, 3, 5, 5, 7, 7, 7, 0]
seting = {i for i in lst} # 生成一個(gè)無(wú)序的集合并且去重{0, 1, 3, 5, 7, 9}
type(seting) # set
字符串
定義字符串
string = "abcde"
字符串的方法
取值 string[num]
取索引 string.index("char")
顯示char子字符的下標(biāo)
len(string)
統(tǒng)計(jì)字符串的長(zhǎng)度
string.count("char")
統(tǒng)計(jì)子字符char的出現(xiàn)次數(shù)
判斷空格和空白字符
string.isspace()
字符串只有空白字符則true
(空字符串則false)
string.isalnum()
字符串有字符且沒(méi)有空白字符則true
(空字符串則false)
判斷字母
string.isalpha()
字符串只包含字母且沒(méi)有空白字符則true
(空字符串則flase)
判斷數(shù)字
string.isdecimal()
字符串只包含數(shù)字則true
可判斷 半角
全角數(shù)字
string.isdigit()
字符串只包含數(shù)字則true
可判斷 半角
全角數(shù)字
unicode特殊數(shù)字
string.isnumeric()
字符串只包含數(shù)字則true
可判斷 半角
全角數(shù)字
unicode特殊數(shù)字
中文數(shù)字
這三個(gè)方法都不能判斷小數(shù)點(diǎn)認(rèn)為小數(shù)點(diǎn)是英文字符
判斷大小寫(xiě)
string.istitle()
如果字符串的每個(gè)單詞首字母大寫(xiě)則true
有空格沒(méi)關(guān)系
string.islower()
如果字符串中有哪怕一個(gè)是能區(qū)分大小寫(xiě)的字符被小寫(xiě)則true
有空格沒(méi)關(guān)系
string.isupper()
如果字符串中有哪怕一個(gè)是能區(qū)分大小寫(xiě)的字符被大寫(xiě)則true
有空格沒(méi)關(guān)系
查找字符串
string.startswith("char")
如果是以char開(kāi)頭則true
string.endswith("char")
如果是以char結(jié)尾則true
string.find (str, start=0, end=len(str))
查詢(xún)字符串是否包含子字符串可指定范圍 有則返回下標(biāo) 沒(méi)有返回-1
string.rfind(str)
反向查詢(xún)
string.index(str)
返回字符串中子字符串的下標(biāo) 沒(méi)有則報(bào)錯(cuò)
string.rindex(str)
反向查詢(xún)
替換字符串
string.capitalize()
將字符串首字符大寫(xiě)
string.title()
將字符串中每個(gè)單詞首字母大寫(xiě)
string.upper()
將字符串中所有小寫(xiě)字符改為大寫(xiě)
string.lower()
將字符串中所有大寫(xiě)字符改為小寫(xiě)
string.swapcase()
翻轉(zhuǎn)字符串中的字母大小寫(xiě)
string.replace(old_str, new_str, num=string.count(str))
返回一個(gè)新的字符串 一次性修改字符串內(nèi)所有子字符串 可以指定修改個(gè)數(shù)
文本對(duì)齊
string.center(num, "char")
居中對(duì)齊并且填充寬度 還可以填充字符
string.ljust(num, "char")
向左對(duì)齊以字符填充
string.rjust(num, " ")
向右對(duì)齊以空格填充
去除空白字符
string.strip("\t\n")
去掉字符串左右的空白字符
string.lstrip("\n")
去掉左邊空白字符
string.rstrip(" ")
去掉右邊空白字符
\t
\n
也可以被去掉
拆分和鏈接
new_list = string.split(str)
以str
為點(diǎn)拆分字符串 輸出一個(gè)列表 如果str
不指定就默認(rèn)包含\r
\n
\t
和空格
list_lines = string.splitlines()
如果string
有換行使用splitlines()
可以以行為單位返回一個(gè)字符串列表
new_string = str.join(seq)
將序列中的每個(gè)元素組成一個(gè)字符串用str
間隔
new_string = " ".join(seq)
以空格鏈接序列 seq
可以是列表
元組
字符串
切片
可以對(duì)list
tuple
str
有序集合切片 無(wú)法對(duì)dict
切片
string[開(kāi)始索引: 結(jié)束索引: 步長(zhǎng)]
返回一個(gè)字符串
如果不指定切片開(kāi)始結(jié)束 string[:]
就是切len(string)
刀
字符串的逆序
string[-1::-1]
從-1向后切再向前移動(dòng)直到頭
公共方法
就是列表
元組
字符串
字典
都可以使用的方法
len()
統(tǒng)計(jì)元素個(gè)數(shù)
del()
刪除變量 或者刪除變量?jī)?nèi)部的元素
max()
顯示容器中最大的值 字典只針對(duì)keys
min()
顯示容器中最小的值 字典只針對(duì)keys
運(yùn)算符
+
合并 * num
重復(fù)
可以合并 重復(fù) str
list
tuple
字典不可以合并 字典使用update()
方法合并并且會(huì)去重
不能交叉合并 list + tuple
邏輯運(yùn)算符
and
or
not
與 或 非
and
遇到假立即返回假
or
遇到真立即返回真
and自左向右掃描布爾表達(dá)式 如果所有表達(dá)式為真 則返回最后一個(gè)為真的表達(dá)式 如果有表達(dá)式為假 立即返回假并且不再向后執(zhí)行
1 and 0 and 3/0 # 立即返回 0 并且不再向后執(zhí)行除0錯(cuò)誤
1 and "0" # 返回最后一個(gè)為真的表達(dá)式結(jié)果
or與and正好相反 自左向右掃描布爾表達(dá)式 如果所有表達(dá)式為假 則返回最后一個(gè)為假的表達(dá)式 如果有表達(dá)式為真 立即返回真并且不再向后執(zhí)行
0 or 1 or 3/0 # 立即返回 1 并且不再向后執(zhí)行除0錯(cuò)誤
0 or "" # 返回最后一個(gè)為假的表達(dá)式結(jié)果
利用and or完成三元表達(dá)式
表達(dá)式 and 表達(dá)式 or 表達(dá)式
計(jì)算的是表達(dá)式的邏輯真假 輸出的是表達(dá)式的結(jié)果
a = 25
b = 5
a > b and a or b # 計(jì)算and兩邊 左右都為真返回第二個(gè)真(a) 第二次計(jì)算 真(a) or b 立即返回真a的值
a < b and a or b # 計(jì)算and兩邊 左邊為假立即返回假(a<b) 第二次計(jì)算 假(a<b) or b 返回真b的值
數(shù)學(xué)運(yùn)算符
+
-
*
/
%
//
**
加 減 乘 除 求余 整除 冪運(yùn)算
成員運(yùn)算符
4 in [1,2,3,4]
返回 true
元素在列表內(nèi)
4 not in (1,2,3)
返回 true
元素不在元組內(nèi)
可以判斷 str
list
tuple
dict
字典只針對(duì)keys
比較運(yùn)算符
比較數(shù)據(jù)的值
==
!=
>
<
<=
>=
返回 True
False
可以比較 str
list
tuple
不能比較字典
注意字符串的比較符合以下規(guī)則 0 < A < a
身份運(yùn)算符
比較數(shù)據(jù)的內(nèi)存地址
is
is not
返回 True
False
a = [1谜诫,2漾峡,3]
b = [1,2喻旷,3]
a == b True
a is b False
變量進(jìn)階
變量
引用數(shù)據(jù)后變量就儲(chǔ)存了數(shù)據(jù)的地址
變量記錄數(shù)據(jù)的地址叫做引用
id()
可以查看變量中引用數(shù)據(jù)的內(nèi)存地址
如果變量已經(jīng)被賦值 再次賦值變量 本質(zhì)上是修改變量的引用
函數(shù)的參數(shù)和返回值 都是通過(guò)引用傳遞
可變和不可變數(shù)據(jù)類(lèi)型
內(nèi)存地址不變的情況下的內(nèi)容的可變和不可變
不可變類(lèi)型
int
float
bool
complex
str
tuple
可變類(lèi)型
list
dict
list
dict
的內(nèi)容可以通過(guò)方法
改變 而且數(shù)據(jù)的地址不會(huì)發(fā)生改變
從內(nèi)存地址的角度講
不可變類(lèi)型被創(chuàng)建后不可以改變內(nèi)容
可變類(lèi)型可以通過(guò)方法改變內(nèi)容而內(nèi)存地址不改變
hash()
哈希是一種算法 作用是提取數(shù)據(jù)的唯一特征碼
哈希
只能接收不可變類(lèi)型
的數(shù)據(jù)
創(chuàng)建字典的鍵值對(duì)時(shí)python會(huì)對(duì)key
進(jìn)行hash
決定如何在內(nèi)存中保存字典的數(shù)據(jù)
所以字典的key
必須是不可變數(shù)據(jù)類(lèi)型
字典中字典和key
儲(chǔ)存在一個(gè)內(nèi)存空間中而value
儲(chǔ)存在其他空間中 value
只是保存了字典的值數(shù)據(jù)的引用
局部變量
在函數(shù)中定義的變量無(wú)法在其他位置使用
不同函數(shù)內(nèi)部可以定義相同名字的變量而不相互影響
全局變量
在函數(shù)外部定義的變量可以在函數(shù)內(nèi)部使用
在函數(shù)內(nèi)部定義已有全局變量名稱(chēng)的變量只是定義局部變量
global num
在函數(shù)內(nèi)申明num是全局變量 然后對(duì)變量的重新賦值會(huì)修改全局變量
全局變量的命名一般加上 g_
或者 gl_
可變參數(shù)和不可變參數(shù)
函數(shù)的參數(shù)通過(guò)引用傳遞
在函數(shù)內(nèi)部重新賦值形參變量只是定義局部變量 不會(huì)影響實(shí)參
在函數(shù)內(nèi)部使用形參變量的方法改變變量數(shù)據(jù)時(shí)會(huì)修改外部的實(shí)參 可變類(lèi)型數(shù)據(jù)
使用列表為參數(shù)傳遞給函數(shù)再在函數(shù)內(nèi)部使用 +=
本質(zhì)上屬于 extend
方法會(huì)改變?nèi)肿兞恐辛斜淼闹?/p>
函數(shù)的缺省值
函數(shù)的某個(gè)參數(shù)相對(duì)固定時(shí) 可以設(shè)置一個(gè)缺省值
缺省參數(shù)應(yīng)該放在函數(shù)形參的最后一個(gè)
如果函數(shù)有多個(gè)缺省參數(shù) 在調(diào)用指定缺省參數(shù)時(shí)需要輸入完整缺省參數(shù)的形參名
?
多值參數(shù)
參數(shù)可以存放多個(gè)數(shù)據(jù)
*args
存放元組參數(shù)
**kwargs
存放字典參數(shù)
在函數(shù)外傳入字典實(shí)參時(shí)候要使用key=value
不能使用key: value
類(lèi)似 增加鍵值對(duì)的操作 dict["key"] = value
裝包
如果需要將多個(gè)值傳遞給多值參數(shù)時(shí)裝包可以簡(jiǎn)化參數(shù)的傳遞
形參 *tuple
**dict
實(shí)參 (1, 2, 3, name="Lee", age=18)
拆包
在函數(shù)內(nèi)部針對(duì)形參使用*tuple
**dict
又可以拆包
字典
的拆包*kwargs
只得到key
**kwargs
得到key:value
a, b = (11, 22)
這也是拆包
操作文件的函數(shù)
file = open("文件名", "訪問(wèn)方式", encoding="UTF8")
打開(kāi)文件 區(qū)分大小寫(xiě) 默認(rèn)"r"
模式打開(kāi)
文件如果存在 返回文件操作對(duì)象 文件如果不存在 拋出異常
在訪問(wèn)方式參數(shù)上加上b
代表用二進(jìn)制方式打開(kāi)文件 理論上open
可以打開(kāi)任何文件 "rb"
"wb"
文件指針
文件指針標(biāo)記了從哪個(gè)位置開(kāi)始讀取數(shù)據(jù)
第一次操作文件前指針默認(rèn)指向文件開(kāi)始的位置
操作文件的方法
read()
一次性讀取所有內(nèi)容 讀取后文件指針會(huì)在文件末尾
readline()
一次讀取一行內(nèi)容 讀取后文件指針會(huì)在下一行的開(kāi)始
write()
將指定內(nèi)容寫(xiě)入文件 寫(xiě)入后指針會(huì)在文件末尾
close()
關(guān)閉文件關(guān)閉文件句柄 fd
如果沒(méi)有關(guān)閉文件 會(huì)消耗系統(tǒng)資源 并且影響后續(xù)對(duì)文件的訪問(wèn)
打開(kāi)文件的參數(shù)
"r"
只讀方式打開(kāi)文件 文件指針將會(huì)放在文件的開(kāi)頭 如果文件不存在 拋出異常
"w"
只寫(xiě)模式打開(kāi)文件 文件指針將會(huì)放在文件的末尾 如果文件存在會(huì)覆蓋內(nèi)容 如果文件不存在會(huì)創(chuàng)建文件并寫(xiě)入
"a"
追加只寫(xiě)模式打開(kāi)文件 文件指針將會(huì)放在文件的末尾 如果文件存在會(huì)追加內(nèi)容 如果文件不存在會(huì)創(chuàng)建文件并寫(xiě)入
"r+"
讀寫(xiě)方式打開(kāi)文件 文件指針將會(huì)放在文件的開(kāi)頭 如果文件不存在 拋出異常
"w+"
讀寫(xiě)方式打開(kāi)文件 文件指針將會(huì)放在文件的末尾 如果文件存在會(huì)覆蓋內(nèi)容 如果文件不存在會(huì)創(chuàng)建文件并寫(xiě)入
"a+"
追加讀寫(xiě)方式打開(kāi)文件 文件指針將會(huì)放在文件的末尾 如果文件存在會(huì)追加內(nèi)容 如果文件不存在會(huì)創(chuàng)建文件并寫(xiě)入
分行讀取文件
readline()
方法一次讀取一行文件對(duì)象的內(nèi)容 執(zhí)行后文件指針會(huì)在讀取行的末尾
readline
分行讀取大文件降低內(nèi)存壓力
file = open("file_path", "r")
while True:
text = file.readline()
if not text:
break
print(text)
file.close()
復(fù)制文件
file_read = open("file_path", "r")
file_write = open("file_path_復(fù)件", "w")
text = file_read.read()
file_write.write(text)
file_read.close()
file_write.close()
分行復(fù)制文件
file_read = open("file_path", "r")
file_write = open("file_path_復(fù)件", "w")
while True:
text = file_read.readline()
file_write.write(text)
if not text:
break
file_read.close()
file_write.close()
文件/目錄的常用管理操作
導(dǎo)入os
模塊 import os
os.system("shell命令")
system方法
可以在python解釋器中執(zhí)行終端命令
文件操作
os.rename("文件名", "新文件名")
重命名文件
os.remove("文件名")
刪除文件
目錄操作
os.listdir("目錄名")
查看目錄內(nèi)容 返回一個(gè)列表
os.mkdir("目錄名")
創(chuàng)建目錄
os.rmdir("目錄名")
刪除目錄
os.getcwd()
獲取工作目錄
os.chdir("目標(biāo)目錄")
修改工作目錄
os.path.isdir("文件路徑")
判斷是不是文件夾 返回bool
文本編碼
python2.x
默認(rèn)ascii
編碼格式
python3.x
默認(rèn)UTF-8
編碼格式
UTF-8
是unicode
編碼的一種編碼格式
漢字在UTF-8
中占3字節(jié)
在*.py
第一行加入 # *-* coding:utf8 *-*
或者 # coding=utf8
指定解釋器使用的編碼
在遍歷或者切片字符串時(shí)即使第一行指定了編碼格式還是會(huì)出錯(cuò) 需要在UTF-8
編碼格式的字符串前加上u"hello世界"
字符串的編碼
string.encode("utf-8")
返回編碼后的字符串 是一個(gè)utf8
的bytes
對(duì)象
data.decode("gbk")
把某種bytes
數(shù)據(jù)解碼成gbk
編碼的字符串
utf8
的bytes
與gbk
的bytes
長(zhǎng)度不同
數(shù)據(jù)結(jié)構(gòu)
?鏈表(linkdelist)
鏈表
由一系列不必在內(nèi)存中相連的結(jié)構(gòu)構(gòu)成 這些對(duì)象按線性順序排序 每個(gè)結(jié)構(gòu)含有表元素和指向后繼元素的指針 最后一個(gè)單元的指針指向NULL 為了方便鏈表的刪除與插入操作 可以為鏈表添加一個(gè)表頭
棧(stack)
棧
是一種受限的線性表 僅允許在表的一端進(jìn)行插入和刪除運(yùn)算 這一端被稱(chēng)為棧頂 另一端稱(chēng)為棧底 向一個(gè)棧插入新元素又稱(chēng)作進(jìn)棧
或壓棧
它是把新元素放到棧頂元素的上面 使之成為新的棧頂元素 從一個(gè)棧刪除元素又稱(chēng)作出棧
或退棧
它是把棧頂元素刪除掉 使其相鄰的元素成為新的棧頂元素
隊(duì)列(queue)
是一種特殊的線性表 是一種先進(jìn)先出
的數(shù)據(jù)結(jié)構(gòu) 只允許在表的前端進(jìn)行刪除操作
而在表的后端進(jìn)行插入操作
進(jìn)行插入操作的端稱(chēng)為隊(duì)尾
進(jìn)行刪除操作的端稱(chēng)為隊(duì)頭
隊(duì)列中沒(méi)有元素時(shí)稱(chēng)為空隊(duì)列
魔法屬性
對(duì)象.__dict__
可以查看對(duì)象的所有屬性
對(duì)象.__doc__
可以查看doc描述
對(duì)象.__class__
查看誰(shuí)創(chuàng)建了該對(duì)象
對(duì)象.__moulde__
查看這個(gè)對(duì)象是由哪個(gè)模塊創(chuàng)建的
def __new__(cls)
創(chuàng)建對(duì)象的內(nèi)存空間
def __init__(self)
初始化實(shí)例對(duì)象的屬性
new
和 init
一起完成了構(gòu)造方法 構(gòu)造方法包括創(chuàng)建內(nèi)存和初始化屬性
def __del__(self):
當(dāng)對(duì)象被銷(xiāo)毀時(shí)會(huì)自動(dòng)調(diào)用此方法
def __call__(self)
當(dāng)執(zhí)行實(shí)例對(duì)象obj()
時(shí) 會(huì)調(diào)用__call__
方法
def __str__(self)
當(dāng)print
對(duì)象時(shí)str
方法返回什么就打印什么 此外 "%s" % 對(duì)象
默認(rèn)調(diào)用對(duì)象的str
方法
class Foo(object):
def __init__(self):
pass
def __str__(self):
return "test"
def __call__(self, num):
print(num)
def __del__(self):
print("death") # 當(dāng)對(duì)象被自動(dòng)銷(xiāo)毀時(shí)會(huì)自動(dòng)調(diào)用del方法
obj = Foo() # 當(dāng)創(chuàng)建對(duì)象時(shí)會(huì)調(diào)用init方法
obj(10) # 當(dāng)實(shí)例對(duì)象使用()時(shí) 調(diào)用的是call方法
print(obj) # 打印的結(jié)果就是str返回的字符串
with和上下文管理器
with as
一般用來(lái)簡(jiǎn)化操作文件時(shí)的清理工作
with
后面的代碼返回的對(duì)象內(nèi)必須有__enter__
方法和__exit__
方法 exit
方法一般包含"清理"代碼(異常處理和退出)
with open("file_path", "r") as f: # 調(diào)用open返回的對(duì)象的enter方法然后把__enter__的返回值賦值給f
print(f) # 如果有異常會(huì)被f的exit方法捕獲并且退出(出錯(cuò)也會(huì)關(guān)閉句柄)
with
后的代碼被求值后返回一個(gè)對(duì)象并且這個(gè)對(duì)象的__enter__()
方法會(huì)被調(diào)用然后把enter
的返回值賦值給as
后的變量f
f
對(duì)象運(yùn)行時(shí)不管異常還是完成運(yùn)行都會(huì)調(diào)用f
的__exit__()
方法進(jìn)行"清理"
上下文管理器
當(dāng)一個(gè)對(duì)象被用作上下文管理器
時(shí)他創(chuàng)建的對(duì)象必須包含這兩個(gè)方法:
-
__enter__
方法將在進(jìn)入代碼塊前被調(diào)用(類(lèi)似init
但是僅用作上下文管理器) -
__exit__
方法則在離開(kāi)代碼塊之后被調(diào)用(即使在代碼塊中遇到了異常)
contextlib模塊
from contextlib import contextmanager
@contextmanager
def my_open(path, mode):
f = open(path, mode)
yield f
f.close()
with my_open("out.txt", "w") as f:
f.write("hello,the simplest context manager")
當(dāng)裝飾器為@contextmanager
標(biāo)記為上下文管理器時(shí)
yield
之前的相當(dāng)于上文yield
后的f
類(lèi)似enter
返回的對(duì)象
yield
下面的相當(dāng)于下文 用作執(zhí)行完write
后的"清理"
isinstance()函數(shù)
isinstance(object, Classinfo)
判斷obj
是不是Class
的實(shí)例 或者obj
是不是Class
的子類(lèi)的實(shí)例 返回bool
判斷對(duì)象是不是可迭代對(duì)象
collections
是python
內(nèi)建的一個(gè)集合模塊 包含許多集合類(lèi)
Iterable
是 collections
模塊中的一個(gè)類(lèi) 所有可以迭代的對(duì)象
都來(lái)自Iterable
類(lèi)
通過(guò) isinstance(a, Iterable)
判斷a
是不是一個(gè)可迭代對(duì)象
迭代器(iterator)
對(duì)于沒(méi)有索引的數(shù)據(jù)類(lèi)型 必須提供一種不依賴(lài)索引的迭代方式
在python
中實(shí)現(xiàn)了__iter__()
方法的對(duì)象是可迭代的
實(shí)現(xiàn)了__next__()
方法的對(duì)象是迭代器
所以讓一個(gè)迭代器工作 至少要實(shí)現(xiàn)__iter__
方法和__next__
方法
如果一個(gè)類(lèi)的對(duì)象想被用于for..in循環(huán)迭代
就必須實(shí)現(xiàn)一個(gè)__iter__()
方法 該方法返回一個(gè)迭代器對(duì)象
for循環(huán)
就會(huì)不斷調(diào)用該迭代器對(duì)象的__next__()
方法拿到循環(huán)的下一個(gè)值 直到遇到StopIteration
錯(cuò)誤時(shí)退出循環(huán)
可迭代對(duì)象和迭代器
class A(object): 可迭代對(duì)象
def __init__(self):
self.list = list()
def add(self, new):
self.list.append(new)
def __iter__(self):
return B(self.list)
class B(object): 迭代器
def __init__(self, list):
self.list = list
num = 0
def __iter__(self): # 此方法表示是一個(gè)可迭代對(duì)象 迭代器必須是一個(gè)可迭代對(duì)象
return None
def __next__(self):
if self.num < len(self.list):
ret = self.list[self.num]
self.num += 1
return ret
else:
raise StopIteration
可迭代對(duì)象必須包含__iter__
方法
__iter__
返回值必須返回一個(gè)迭代器
才可以實(shí)現(xiàn)迭代
包含__iter__
方法和__next__
方法的叫做迭代器
也是可迭代對(duì)象
for
循環(huán)或者next()
函數(shù)取值時(shí)會(huì)每次取對(duì)象的iter
方法所返回的對(duì)象里的next
方法實(shí)現(xiàn)迭代
簡(jiǎn)化實(shí)現(xiàn)迭代器
class Iterable_A(object):
def __init__(self):
self.list = [11, 22, 33]
self.num = 0
def __iter__(self):
return self
def __next__(self):
if self.num < len(self.list)
ret = self.list[self.num]
self.num += 1
return ret
else:
raise StopIteration
使用迭代器的好處
python2
中 range(x)
生成x
個(gè)元素的列表 占用大量
內(nèi)存空間
xrange(x)
返回一個(gè)對(duì)象
這個(gè)對(duì)象保存了生成x個(gè)元素列表的方法
使用一個(gè)生成一個(gè) 節(jié)約內(nèi)存
空間
python3
中已經(jīng)用xrange
替換了range
生成器(generator)
yield
生成器的特點(diǎn) 讓代碼暫停
生成器
也是一個(gè)迭代器
(特殊的迭代器) 使用一次生成一個(gè)對(duì)象 節(jié)約內(nèi)存空間
如果一個(gè)函數(shù)中有yield
語(yǔ)句 那么他會(huì)變?yōu)橐粋€(gè)創(chuàng)建生成器的類(lèi)
當(dāng)for
循環(huán)這個(gè)生成器對(duì)象取值或者使用next(obj)
函數(shù)取值時(shí) 程序執(zhí)行到yield
會(huì)返回yield
后的值并暫停
下次循環(huán)時(shí)會(huì)從yield
后開(kāi)始執(zhí)行 直到循環(huán)結(jié)束退出
obj.send(None)
同樣具有next(obj)
的功能并且可以傳入生成器一個(gè)值
send()
的參數(shù)如果不為None
則是把yield xx
這個(gè)整體當(dāng)做一個(gè)表達(dá)式 并把參數(shù)傳入表達(dá)式 然后可以賦值給yield xx
左邊的變量
如果第一次啟動(dòng)生成器時(shí)就用send()
并且傳入一個(gè)值 會(huì)報(bào)錯(cuò)
第一次執(zhí)行暫停在yield xx
因此傳入的值沒(méi)有變量保存 所以啟動(dòng)生成器
時(shí)用next()
后續(xù)才可以使用send(msg)
傳入?yún)?shù)
通過(guò)next()函數(shù)取值生成器
def fib(nums):
a = 0
b = 1
count = 0
while count < nums:
yield a
a, b = b, a+b
count += 1
return "done...."
nums_obj = fib(10)
while True:
try:
ret = next(nums_obj)
print(ret)
except Exception as x:
print(x.value)
break
此時(shí)nums_obj
是一個(gè)yield
模板創(chuàng)建的生成器對(duì)象 使用next()
函數(shù)取值生成器
如果要在迭代結(jié)束后返回一個(gè)值就在創(chuàng)建生成器的函數(shù)中使用return
返回內(nèi)容
并且在next
取值結(jié)束時(shí)捕獲異常
并調(diào)用捕獲到異常的對(duì)象的value
屬性就可以顯示return
的結(jié)果了
next()函數(shù)
next()
函數(shù)可以取值迭代器
也可以取值生成器
迭代器: next(迭代器) 每次取值時(shí)執(zhí)行迭代器
的__next__
方法并返回給外部的next()
生成器: next(生成器) 每次取值時(shí) yield
把 a
的值返回給外部的 next()
send(msg)函數(shù)
send()
函數(shù)只可以取值生成器
send(msg)
的過(guò)程分為2步
-
msg
被傳入函數(shù)內(nèi)的yield a
這個(gè)整體
并賦值給yield a
左邊的變量
-
yield
把a
的值返回給外部的send()
深拷貝淺拷貝
copy模塊
import copy
deepcopy 可以完成深拷貝
b = copy.deepcopy(a)
copy 可以完成淺拷貝
d = copy.copy(c)
[11,22,[33,44]]
淺拷貝
可變數(shù)據(jù)類(lèi)型只是拷貝第一層
到新的內(nèi)存空間而嵌套的數(shù)據(jù)不拷貝還是僅僅是指向
深拷貝
可變數(shù)據(jù)類(lèi)型時(shí)是遞歸拷貝所有數(shù)據(jù)到一個(gè)新的內(nèi)存空間
(11,22,(33,44))
當(dāng)拷貝一個(gè)完全是由不可變數(shù)據(jù)類(lèi)型組成的數(shù)據(jù)時(shí) 淺拷貝和深拷貝都只是拷貝引用
(11,22,[33,44])
淺拷貝
一個(gè)不可變數(shù)據(jù)類(lèi)型包含可變數(shù)據(jù)類(lèi)型的數(shù)據(jù)時(shí)只是拷貝第一層
深拷貝
一個(gè)不可變數(shù)據(jù)類(lèi)型只要其中包含任何可變數(shù)據(jù)類(lèi)型
都會(huì)全部遞歸拷貝到一個(gè)新的內(nèi)存空間
面相對(duì)象基礎(chǔ)
面相過(guò)程
是以過(guò)程為中心編程思想 以什么正在發(fā)生為主要目標(biāo)進(jìn)行編程
面向?qū)ο?/code> 是把過(guò)程中的事物分解成各個(gè)對(duì)象并賦予對(duì)象在解決問(wèn)題過(guò)程中事物的行為
面向?qū)ο蟮娜筇攸c(diǎn)
封裝
根據(jù)職責(zé)將對(duì)象的屬性和方法封裝到抽象的類(lèi)中
繼承
子類(lèi)擁有父類(lèi)的所有屬性和方法從而實(shí)現(xiàn)代碼的復(fù)用
多態(tài)
不同的子類(lèi)的對(duì)象調(diào)用相同的父類(lèi)方法產(chǎn)生不同的執(zhí)行結(jié)果(通過(guò)重寫(xiě)父類(lèi)方法)
面向?qū)ο蟮姆椒?/h6>
dir(對(duì)象)
可以查看針對(duì)對(duì)象的所有方法和屬性
print(對(duì)象)
顯示對(duì)象是由哪個(gè)類(lèi)創(chuàng)建的以及類(lèi)的內(nèi)存地址(前提是對(duì)象沒(méi)有實(shí)現(xiàn)__str__
方法)
id(對(duì)象)
以十進(jìn)制方式顯示對(duì)象的內(nèi)存地址
內(nèi)置方法
__doc__
查看類(lèi)內(nèi)部的說(shuō)明文檔
?__new__
為對(duì)象分配內(nèi)存空間 return
父類(lèi)的new
方法實(shí)現(xiàn)返回對(duì)象的引用為了后續(xù)傳入init
方法self初始化對(duì)象屬性
__init__
初始化實(shí)例對(duì)象的屬性 用作定義實(shí)例屬性
__del__
對(duì)象被從內(nèi)存刪除時(shí)會(huì)自動(dòng)調(diào)用此方法
__str__
返回對(duì)象的描述信息 print
對(duì)象時(shí)輸出指定字符串 配合return
返回字符串
類(lèi)
具有相同屬性或者方法的事物的統(tǒng)稱(chēng) 不能直接使用
類(lèi)命名的時(shí)候要滿足大坨峰命名法
被使用的類(lèi)應(yīng)該先開(kāi)發(fā)
對(duì)象的屬性可以是另一個(gè)類(lèi)創(chuàng)建的對(duì)象 新兵的槍屬性是由槍類(lèi)創(chuàng)建的槍對(duì)象
python3.x
中所有類(lèi)的父類(lèi)都是object
類(lèi)
新式類(lèi):以object
為基類(lèi)的類(lèi)
經(jīng)典類(lèi):不以object
為基類(lèi)的類(lèi)
定義類(lèi)
class Human(object):
def __new__(cls):
return super().__new__(cls)
def __init__(self, name):
self.name = name
self.age = 18
def work(self):
print("working")
在對(duì)象方法內(nèi)部使用self.
可以訪問(wèn)和調(diào)用對(duì)象自己的屬性和方法
在初始化方法中設(shè)置對(duì)象屬性 self.name = "tom"
在主程序中臨時(shí)設(shè)置對(duì)象屬性 實(shí)例對(duì)象.name = "tom"
對(duì)象
由類(lèi)
創(chuàng)建出來(lái)的一個(gè)具體存在
哪個(gè)類(lèi)創(chuàng)建出來(lái)的對(duì)象就擁有哪個(gè)類(lèi)包含的屬性和方法
類(lèi)
可以創(chuàng)建多個(gè)對(duì)象
多個(gè)對(duì)象的屬性和方法互不干擾作用域?yàn)閷?duì)象自己
創(chuàng)建對(duì)象的過(guò)程
man = Human("士兵")
實(shí)例化Human
?__new__(cls)
為對(duì)象分配內(nèi)存空間 返回對(duì)象的引用self
__init__(self, 參數(shù)....)
獲取new
返回的對(duì)象引用
接收外部傳入的參數(shù) 為實(shí)例對(duì)象初始化屬性
單繼承
class 類(lèi)名(父類(lèi)名):
子類(lèi)擁有父類(lèi)所有
的方法和屬性
子類(lèi)可以直接使用父類(lèi)中已經(jīng)封裝好的屬性和方法
子類(lèi)應(yīng)該繼續(xù)根據(jù)職責(zé)封裝子類(lèi)特有的屬性和方法
多繼承
class 子類(lèi)(父類(lèi)1, 父類(lèi)2,....):
多個(gè)父類(lèi)有同名屬性和方法 子類(lèi)調(diào)用屬性和方法依據(jù) MRO方法解決順序
執(zhí)行
盡量避免多繼承有同名屬性和方法的父類(lèi)
MRO方法解決順序
print(類(lèi)().__mro__)
查看類(lèi)的方法搜索順序
繼承的傳遞性
子類(lèi)擁有父類(lèi)的屬性和方法 子類(lèi)的子類(lèi)也擁有父類(lèi)的父類(lèi)的屬性和方法
方法的重寫(xiě)
覆蓋
父類(lèi)的方法無(wú)法滿足子類(lèi)時(shí)在子類(lèi)中重新定義同名方法 調(diào)用時(shí)會(huì)調(diào)用子類(lèi)重寫(xiě)的方法不會(huì)調(diào)用原先父類(lèi)的方法
擴(kuò)展
在覆蓋的基礎(chǔ)上使用 super().方法()
調(diào)用父類(lèi)方法實(shí)現(xiàn) 再添加擴(kuò)展內(nèi)容
重寫(xiě)new方法
class 類(lèi)(object):
def __new__(cls): # 定義cls變量保存類(lèi)的引用
return super(類(lèi), 類(lèi)對(duì)象).__new__(cls) # cls 表示要讓哪一個(gè)對(duì)象實(shí)現(xiàn)此方法
返回父類(lèi)的new
方法實(shí)現(xiàn)得到當(dāng)前類(lèi)的實(shí)現(xiàn)對(duì)象的引用給cls
變量 變量?jī)?nèi)容會(huì)在new
執(zhí)行完畢傳遞給當(dāng)前類(lèi)的self
如果返回的不是方法實(shí)現(xiàn)
而是一個(gè)其他類(lèi)創(chuàng)建的實(shí)例引用
那么會(huì)執(zhí)行其他類(lèi)的init
方法 不會(huì)執(zhí)行當(dāng)前類(lèi)的init
方法
super(類(lèi), 對(duì)象).init()
對(duì)象在類(lèi)中的MRO列表
的下一個(gè)搜索類(lèi)中init
的方法實(shí)現(xiàn)
私有屬性和私有方法
通過(guò)名字重整
的方式改變?cè)O(shè)置的私有屬性名而達(dá)到無(wú)法直接訪問(wèn)私有屬性或方法的目的
無(wú)法在外界直接訪問(wèn) 只能在類(lèi)范圍中訪問(wèn)
self.__age
私有屬性
self.__secret()
私有方法
強(qiáng)行訪問(wèn)私有屬性demo._Women__age
強(qiáng)行訪問(wèn)私有方法demo._Women__secret()
?子類(lèi)的對(duì)象 不能在自己的方法內(nèi)部 直接訪問(wèn)父類(lèi)的私有屬性或私有方法
子類(lèi)的對(duì)象 可以通過(guò)繼承自父類(lèi)的公有方法 間接訪問(wèn)到父類(lèi)的私有屬性或私有方法
x
公有屬性或方法
_x
屬性或者方法 在使用import *
導(dǎo)入的時(shí)候不會(huì)被導(dǎo)入
__x
私有屬性或方法 無(wú)法被繼承
__x__
內(nèi)置屬性或方法 可以被繼承
x_
屬性或方法 用于避免名稱(chēng)與關(guān)鍵字名沖突 比如list_ = [1,2,3]
多態(tài)
是調(diào)用方法的技巧
不會(huì)影響類(lèi)的內(nèi)部設(shè)計(jì)
通過(guò)重寫(xiě)
或擴(kuò)展
父類(lèi)方法 以不同子類(lèi)的對(duì)象 調(diào)用相同的父類(lèi)方法產(chǎn)生不同的執(zhí)行結(jié)果
實(shí)例對(duì)象
定義實(shí)例對(duì)象
obj = 類(lèi)()
使用類(lèi)()
創(chuàng)建實(shí)例對(duì)象的步驟有兩步:
- 在內(nèi)存中為對(duì)象分配空間
- 調(diào)用
init
方法為對(duì)象初始化屬性
類(lèi)創(chuàng)建出來(lái)的對(duì)象叫做類(lèi)的實(shí)例
類(lèi)創(chuàng)建實(shí)例對(duì)象的動(dòng)作叫做實(shí)例化
實(shí)例對(duì)象的屬性叫做實(shí)例屬性
實(shí)例對(duì)象調(diào)用的方法叫做實(shí)例方法
實(shí)例對(duì)象各自擁有自己的實(shí)例屬性 保存在各自的內(nèi)存中
實(shí)例方法只有一份 保存在類(lèi)對(duì)象
的內(nèi)存中
實(shí)例對(duì)象通過(guò)self.
傳遞引用到類(lèi)對(duì)象
實(shí)現(xiàn)自己的方法
在調(diào)用屬性時(shí)把實(shí)例對(duì)象的引用傳遞到實(shí)例對(duì)象
的內(nèi)部
在調(diào)用方法時(shí)把實(shí)例對(duì)象的引用傳遞到類(lèi)對(duì)象
的內(nèi)部
類(lèi)對(duì)象
定義類(lèi)對(duì)象
class 類(lèi)(object):
類(lèi)在運(yùn)行時(shí)也會(huì)被加載到內(nèi)存中 ==>類(lèi)對(duì)象
類(lèi)對(duì)象
的內(nèi)存中保存著實(shí)例對(duì)象的方法
方法只有一份 實(shí)例分別傳遞引用調(diào)用方法
除了封裝實(shí)例對(duì)象的屬性和方法外 類(lèi)對(duì)象還可以擁有自己的類(lèi)屬性
和類(lèi)方法
類(lèi)屬性
針對(duì)類(lèi)對(duì)象定義的屬性 只用來(lái)描述類(lèi)對(duì)象的特征
定義類(lèi)屬性
count = 0
使用賦值語(yǔ)句在類(lèi)中定義類(lèi)屬性
調(diào)用類(lèi)屬性
類(lèi)對(duì)象.類(lèi)屬性
-
實(shí)例.類(lèi)屬性()
不推薦 容易混淆實(shí)例.類(lèi)屬性 = value
會(huì)創(chuàng)建一個(gè)同名實(shí)例屬性 而不會(huì)修改類(lèi)屬性
python
中屬性的獲取遵循向上查找機(jī)制
如果此類(lèi)中沒(méi)有該類(lèi)屬性會(huì)向上在父類(lèi)中查找
實(shí)例在調(diào)用屬性時(shí)在init
中找不到同名屬性會(huì)到類(lèi)中查找屬性 但是訪問(wèn)的實(shí)際是類(lèi)屬性
類(lèi)方法
針對(duì)類(lèi)對(duì)象定義的方法 用來(lái)實(shí)現(xiàn)類(lèi)對(duì)象的行為
要在類(lèi)中使用類(lèi)本身 就使用類(lèi)方法 因?yàn)轭?lèi)方法的第一個(gè)參數(shù)就是類(lèi)本身
定義類(lèi)方法
@classmethod
def 方法名(cls):
使用裝飾器@classmethod
聲明這是一個(gè)類(lèi)方法
類(lèi)方法的第一個(gè)參數(shù)是cls
哪一個(gè)類(lèi)調(diào)用的方法cls
就是哪一個(gè)類(lèi)的引用
調(diào)用類(lèi)方法
類(lèi)對(duì)象.類(lèi)方法()
類(lèi)方法不需要實(shí)例化類(lèi)就可以通過(guò)類(lèi)對(duì)象來(lái)調(diào)用
靜態(tài)方法
類(lèi)中封裝的方法沒(méi)有訪問(wèn)實(shí)例屬性
和類(lèi)屬性的需求
應(yīng)該定義為靜態(tài)方法
定義靜態(tài)方法
@staticmethod
def 方法名():
使用修飾器@staticmethod
聲明這是一個(gè)靜態(tài)方法
靜態(tài)方法的第一個(gè)參數(shù)不需要定義
方法內(nèi)部無(wú)法
訪問(wèn)實(shí)例屬性
和類(lèi)屬性
實(shí)例方法默認(rèn)第一個(gè)參數(shù)是self
類(lèi)方法默認(rèn)第一個(gè)參數(shù)是cls
靜態(tài)方法默認(rèn)沒(méi)有參數(shù)
調(diào)用靜態(tài)方法
類(lèi).靜態(tài)方法()
靜態(tài)方法不需要實(shí)例化類(lèi)就可以通過(guò)類(lèi)來(lái)調(diào)用該方法
特點(diǎn)是不需要?jiǎng)?chuàng)建對(duì)象就可以調(diào)用 高效率
定義方法的規(guī)則
實(shí)例方法
---當(dāng)方法內(nèi)部需要訪問(wèn)實(shí)例屬性和類(lèi)屬性
類(lèi)方法
---當(dāng)方法內(nèi)部只需要訪問(wèn)類(lèi)屬性
靜態(tài)方法
---當(dāng)方法內(nèi)部不需要訪問(wèn)實(shí)例屬性和類(lèi)屬性
property裝飾器
讓一個(gè)類(lèi)中的方法經(jīng)過(guò)復(fù)雜計(jì)算后返回一個(gè)值并且在調(diào)用時(shí)變得簡(jiǎn)單直觀
調(diào)用時(shí)直接使用對(duì)象.方法名
而不使用對(duì)象.方法()
調(diào)用一個(gè)方法像調(diào)用一個(gè)屬性一樣 并且property裝飾器
讓方法在調(diào)用時(shí)避免了是否要傳參的疑問(wèn)
新式類(lèi)
中property裝飾器
有三種分別get
set
和 del
@property
本身又會(huì)創(chuàng)建其他的裝飾器@xxx.setter
@xxx.deleter
@property
用于get
返回的值 通過(guò)對(duì)象.方法名
get
@xxx.setter
用于set
變量的值 通過(guò)對(duì)象.方法名 = num
set
@xxx.deleter
用于del
設(shè)置的變量 通過(guò) del 對(duì)象.方法名
del
class Goods(object):
def __init__(self):
self.original_price = 100
self.discount = 0.8
@property
def price(self):
new_price = self.original_price * self.discount
return new_price
@price.setter
def price(self, value):
self.original_price = value
@price.deleter
def price(self):
del self.original_price
obj = Goods()
obj.price # get價(jià)格
obj.price = 200 # set價(jià)格
del obj.price # 刪除商品價(jià)格
通過(guò)類(lèi)屬性設(shè)置property
在類(lèi)中property()
函數(shù)設(shè)置property屬性
返回一個(gè)property對(duì)象
類(lèi)屬性BARBAR = property(fget=None, fset=None, fdel=None, doc=None)
property
函數(shù)有四個(gè)參數(shù)
第一個(gè)參數(shù)填入方法名
調(diào)用obj.BAR
時(shí)自動(dòng)調(diào)用fset
設(shè)置的方法
第二個(gè)參數(shù)填入方法名
調(diào)用obj.BAR = xxx
時(shí)自動(dòng)調(diào)用fset
設(shè)置的方法將xxx
傳入第二個(gè)參數(shù)
第三個(gè)參數(shù)填入方法名
調(diào)用del obj.BAR
時(shí)自動(dòng)調(diào)用fdel
方法
第四個(gè)參數(shù)填入字符串
Foo.BAR.__doc__
返回一個(gè)字符串對(duì)象
class Foo():
def get_bar(self):
bar = "python"
return bar
def set_bar(self, value):
bar = value
return bar
def del_bar(self):
del bar
BAR = property(get_bar, set_bar, del_bar, "description..")
obj = Foo()
obj.BAR # 調(diào)用property參數(shù)(將get_bar方法變?yōu)榱藀roperty屬性)
obj.BAR = "World" # 調(diào)用第二個(gè)參數(shù)
del obj.BAR # 調(diào)用第三個(gè)參數(shù)
desc = Foo.BAR.__doc__ # 獲取第四個(gè)參數(shù)中設(shè)置的字符串
print(desc)
單例模式
讓類(lèi)創(chuàng)建的對(duì)象只有一個(gè)實(shí)例
對(duì)象的內(nèi)存地址每次返回都是相同的
super()類(lèi)
super()
調(diào)用父類(lèi)方法實(shí)現(xiàn)的方式區(qū)別于直接使用父類(lèi)名調(diào)用父類(lèi)方法
通過(guò)C3算法
的結(jié)果保存在MRO
中 通過(guò)MRO順序
可以避免鉆石問(wèn)題時(shí)實(shí)現(xiàn)一個(gè)父類(lèi)方法會(huì)多次調(diào)用多繼承的父類(lèi)方法實(shí)現(xiàn)
C3算法
避免了多繼承時(shí)子類(lèi)多次調(diào)用父類(lèi)方法實(shí)現(xiàn)
super().__init__(參數(shù)1,參數(shù)2,*args,**kwargs)
避免多繼承報(bào)錯(cuò) 可以使用不定長(zhǎng)參數(shù)接收參數(shù)
定義單例模式
class 類(lèi)(object):
i = None # 設(shè)置空對(duì)象
def __new__(cls): # 實(shí)例化類(lèi)時(shí)首先讀取這行代碼
if cls.i is None:
cls.i = super().__new__(cls)
return cls.i
return cls.i
單次初始化
class 類(lèi)(object):
init_flag = False # 創(chuàng)建類(lèi)屬性初始設(shè)置為False
def __init__(self):
if 類(lèi).init_flag is False:
.........
類(lèi).init_flag = True # 當(dāng)init執(zhí)行后更改類(lèi)屬性值為T(mén)rue
return
創(chuàng)建類(lèi)屬性init_flag
標(biāo)記是否執(zhí)行過(guò)初始化動(dòng)作
異常
解釋器遇到錯(cuò)誤會(huì)停止并提示錯(cuò)誤信息
提示錯(cuò)誤信息的動(dòng)作叫做拋出raise
異常
錯(cuò)誤信息的第一個(gè)單詞是錯(cuò)誤類(lèi)型
捕獲異成荩基本語(yǔ)法
try:
pass
except:
pass
捕獲類(lèi)型異常
try:
pass
except 錯(cuò)誤類(lèi)型:
pass
捕獲未知異常
Exception
是一個(gè)錯(cuò)誤的基類(lèi)
except Exception
可以捕獲所有預(yù)想到的異常以外的異常
except Exception as 變量:
把捕獲到的異常賦值給as
后的變量
try:
pass
except Exception as 變量:
print(變量)
捕獲異常的完整語(yǔ)法
try
語(yǔ)法中只有except
才會(huì)捕獲異常 被捕獲的異常不會(huì)繼續(xù)傳遞 finally
不會(huì)終止傳遞異常
上下文管理器
中exit
方法類(lèi)似于finally
雖然會(huì)執(zhí)行一些代碼 但是不會(huì)捕獲異常
try:
pass # 嘗試的代碼
except:
pass # 有異常會(huì)執(zhí)行的代碼
except 錯(cuò)誤類(lèi)型1:
pass # 有錯(cuò)誤類(lèi)型1會(huì)執(zhí)行的代碼
except (錯(cuò)誤類(lèi)型2, 錯(cuò)誤類(lèi)型3):
pass # 有錯(cuò)誤類(lèi)型2 或 錯(cuò)誤類(lèi)型3 會(huì)執(zhí)行的代碼
except Exception as 變量: # 以上捕獲異常都沒(méi)有預(yù)料到的異常會(huì)在捕獲未知異常里被捕獲
print(變量) # 有未知異常時(shí)會(huì)執(zhí)行的代碼 打印錯(cuò)誤信息
else:
pass # 嘗試的代碼沒(méi)有異常會(huì)執(zhí)行的代碼
finally:
pass # 無(wú)論有沒(méi)有異常都會(huì)執(zhí)行的代碼
異常的傳遞
當(dāng)函數(shù)
或方法
出現(xiàn)錯(cuò)誤 會(huì)將異常傳遞給 函數(shù)
或方法
的調(diào)用一方 當(dāng)異常傳遞到主程序時(shí)仍沒(méi)有處理異常 程序才會(huì)終止
為保證函數(shù)
或方法
中的代碼簡(jiǎn)潔 一般在主程序中捕獲異常
主動(dòng)拋出raise
異常
針對(duì)特有的業(yè)務(wù)需求主動(dòng)拋出異常
再由其他專(zhuān)門(mén)捕獲異常的程序處理異常
- 函數(shù)中以條件拋出異常:
def xxx():
if (條件)xxx: # 設(shè)置當(dāng)達(dá)到某個(gè)條件后就是異常
ex = Exception("自定義異常信息") # 創(chuàng)建異常包含此錯(cuò)誤信息的異常
raise ex # 拋出異常
return xxx # 拋出異常后不會(huì)執(zhí)行后續(xù)代碼 如果沒(méi)有異常return正常結(jié)果
- 捕獲異常:
try:
xxx() # 內(nèi)部拋出了異常 還需要捕獲
except Exception as 變量: # 捕獲xxx()傳遞的未知異常
print(變量) # 打印自定義異常信息
模塊
導(dǎo)入模塊
import 模塊1
import 模塊2 # (PEP8)
import 模塊1, 模塊2 # (不推薦使用)
如果變量中存儲(chǔ)了模塊名 直接使用import導(dǎo)入的是變量名.py 此時(shí)需要使用__import__()
來(lái)導(dǎo)入
__import__(變量名)
返回一個(gè)對(duì)象 這個(gè)對(duì)象就是模塊的引用
使用getattr(obj, name[, default])
函數(shù) 返回一個(gè)對(duì)象的屬性值
obj -- 對(duì)象。
name -- 字符串且预,對(duì)象屬性牺陶。 name 只是名字 而返回值 是這個(gè)屬性的引用
default -- 默認(rèn)返回值,如果不提供該參數(shù)辣之,在沒(méi)有對(duì)應(yīng)屬性時(shí),將觸發(fā) AttributeError皱炉。
module_ = ___import___(變量名)
method_ = getattr(module_, name)
導(dǎo)入模塊時(shí)的順序
1.官方標(biāo)準(zhǔn)模塊
2.第三方模塊
3.應(yīng)用程序模塊
首先從當(dāng)前目錄下搜索要導(dǎo)入的模塊 再?gòu)南到y(tǒng)目錄搜索要導(dǎo)入的內(nèi)置模塊
模塊.__file__
內(nèi)置屬性 可以查看模塊的完整路徑
sys
模塊中sys.path
是一個(gè)列表其中的順序表示導(dǎo)入模塊時(shí)搜索模塊的順序
使用列表的sys.path.insert(0, "./")
來(lái)插入一個(gè)新模塊包路徑
使用sys.path.append("/")
來(lái)追加一個(gè)路徑
程序在執(zhí)行期間對(duì)程序?qū)脒^(guò)的模塊的修改不會(huì)生效
需要在程序中使用 imp
模塊中的reload()
方法來(lái)重新加載修改過(guò)的模塊reload(模塊)
導(dǎo)入一個(gè)模塊的兩個(gè)步驟 定義一個(gè)common
的變量 common
指向一個(gè)模塊中的文件
from common import A
import common
common.A = 1
A = 1
這兩種方式的區(qū)別在于
common.A = 1
會(huì)修改common
中A
的值為1
A = 1
讓一個(gè)變量A
指向1
調(diào)用模塊中的工具
模塊.全局變量
模塊.函數(shù)()
obj = 模塊.類(lèi)()
指定模塊的別名
import 模塊 as 模塊別名
模塊別名要滿足大駝峰命名法
有重名沖突的導(dǎo)入時(shí)使用as
設(shè)置模塊別名
導(dǎo)入部分工具
from 模塊 import 工具
導(dǎo)入模塊的指定工具 調(diào)用時(shí)直接使用導(dǎo)入的工具名
from 模塊 import *
導(dǎo)入所有工具 調(diào)用時(shí)直接使用模塊內(nèi)的工具名
使用import
導(dǎo)入多個(gè)同名模塊會(huì)執(zhí)行后導(dǎo)入的模塊內(nèi)容
模塊測(cè)試代碼
模塊被導(dǎo)入時(shí)所有沒(méi)有縮進(jìn)的代碼都會(huì)被執(zhí)行
模塊.__name__
內(nèi)置屬性 可以輸出模塊名 如果在模塊內(nèi)部調(diào)用會(huì)輸出__main__
在其他文件中執(zhí)行輸出模塊名
if __name__ == "__main__":
判斷__name__
被執(zhí)行時(shí)是不是輸出__main__
來(lái)決定是否輸出下方測(cè)試代碼
包(Package)
包含多個(gè)模塊的特殊目錄
包文件夾命名時(shí)遵循變量命名規(guī)則
import 包
可以導(dǎo)入包中所有的模塊
在包目錄下創(chuàng)建__init__.py
對(duì)外界提供包內(nèi)模塊的列表
__init__.py
from ./ import 模塊1
from ./ import 模塊2
發(fā)布模塊
在包的同級(jí)目錄下創(chuàng)建 setup.py
setup.py
from distutils.core import setup
setup(name="st_message", # 包名
version="1.0", # 版本號(hào)
description="發(fā)送和接收消息模塊", # 描述信息
long_description="完整的發(fā)送和接收消息模塊", # 完整描述信息
author="lee", # 作者
author_email="lee@lee.com", # 作者郵箱
url="lee.com", # 主頁(yè)
py_modules=[
"st_message.send_message",
"st_message.receive_message"
])
構(gòu)建模塊
$ python3 setup.py build
會(huì)構(gòu)建出需要打包發(fā)布的文件
生成發(fā)布?jí)嚎s包
$ python3 setup.py sdist
會(huì)打包構(gòu)建出的文件 使用不同解釋器打包不同版本的發(fā)布?jí)嚎s包
安裝模塊
$ tar -zxvf st_message.tar.gz
$ sudo python3 setup.py install
卸載模塊
$ sudo rm -r /usr/local/lib/python3.7/dist-package/st_message*
安裝python3第三方模塊
pip3
是用來(lái)安裝python3第三方模塊的工具
$sudo pip3 install pygame # 安裝模塊
$sudo pip3 uninstall pygame # 卸載模塊
$pip3 list # 查看安裝的所有包
$pip3 freeze # 查看安裝的所有包并顯示版本號(hào) 用于遷移
$pip3 install django==1.8.2 # 指定包的版本
虛擬環(huán)境
安裝虛擬環(huán)境插件
真實(shí)python環(huán)境的復(fù)制版本 只有Python的環(huán)境被復(fù)制
$sudo pip3 install virtualenv 安裝虛擬環(huán)境
$sudo pip3 install virtualenvwrapper 安裝虛擬環(huán)境擴(kuò)展包 用于簡(jiǎn)化虛擬環(huán)境的使用
配置插件
編輯.bashrc
環(huán)境變量文件
export WORKON_HOME=$HOME/.virtualenvs # 設(shè)置虛擬環(huán)境文件位置
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 # 設(shè)置python位置
export VIRTUALENVWRAPPER_VIRTUALENV=/usr/local/bin/virtualenv # 設(shè)置virtualenv位置
source /usr/local/bin/virtualenvwrapper.sh # 加載virtualenvwrapper插件
運(yùn)行source .bashrc
重新加載.bashrc
文件使設(shè)置生效
創(chuàng)建虛擬環(huán)境
$mkvirtualenv -p python3 環(huán)境名 # 創(chuàng)建python3虛擬環(huán)境
刪除虛擬環(huán)境
$rmvirtualenv 環(huán)境名 # 刪除指定虛擬環(huán)境
查看所有虛擬環(huán)境
$lsvirtualenv # 顯示所有虛擬環(huán)境
切換虛擬環(huán)境
$workon 環(huán)境名 # 切換虛擬環(huán)境
退出虛擬環(huán)境
$deactivate # 退出虛擬環(huán)境
注意: 在虛擬環(huán)境
中不能使用sudo來(lái)安裝 使用sudo pip
安裝 會(huì)安裝到真實(shí)python環(huán)境