一、pycharm的使用和python基本語法
(一)、pycharm的使用和python環境
1、python以及pycharm的安裝
- python 的版本選擇:3.x 版本,不要安裝2.x 版本,有很多語法不一樣
- 如何確定自己 python 版本: cmd: python
- 不是內部命令:python沒有正確安裝,原因大概率是因為沒有配置環境變數(配置環境變數後重啟電腦生效)
- 指定 python 的安裝目錄:一般來說是安裝在 d:\python37
- 測試python是否安裝成功
- cmd: python
- cmd: pip ,或者 pip3 , 有任何一個出現命令不存在,
- 額外注意:loadrunner 中也有pip,這個pip配置環境變數了之後,python中的pip也需要配置環境變數
- prcharm 的版本選擇:社群版夠用
- pycharm 只是一個工具,python 才是關鍵
2、pycharm 新建專案
- 新建專案
- file ---> New Project
- 退出專案
- file ---> Close Project
- 切換專案
- file ---> Open
- file ---> Open Recent
3、檔案、目錄、包的建立和管理
- Project ---> 右鍵 ,可以新建檔案、目錄和包
4、pycharm 的基礎使用
- python 程式碼是儲存到以 .py 結尾的檔案當中
- .py 檔案又是放到各個資料夾(目錄)下面的
5、如何執行程式碼:
- 右鍵,點選 run
- 命令列執行:點選底下的 Terminal
- 進入專案路徑
- python 拼接好的路徑/python檔案.py
6、安裝第三方庫
-
第三方庫:是別人已經寫好的 python 程式碼
-
第一種方法:
- 安裝:pip install 庫名
- 解除安裝:pip uninstall 庫名
-
第二種方法:pycharm :不要勾選 user's site package
-
第三種方法:庫放在國外的伺服器上,需要用到國內安裝源,python國內源
- pip install 庫名 -i 源地址
- pip install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple
python國內源:
清華:https://pypi.tuna.tsinghua.edu.cn/simple
阿里雲:http://mirrors.aliyun.com/pypi/simple/
中國科技大學 https://pypi.mirrors.ustc.edu.cn/simple/
華中理工大學:http://pypi.hustunique.com/
山東理工大學:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/
(二)、python基本語法
1、基本語法
-
print 輸出
- 表示在螢幕上列印出(顯示出)
- 使用的任何的程式碼,雙引號是半形,英文
- print 預設輸出是換行的,不同的資料之間用逗號隔開
-
python註釋: 表示在 python 當中不會執行的文字(不會當成程式碼), 是說明下面的程式碼是什麼?
- # 表示單行註釋 , Ctrl + /
- """ """ 表示多行註釋
- ''' ''' 表示多行註釋
-
縮排:
- 現在這個階段,所有的程式碼全部頂格寫,不要進行縮排。
-
數值
- 和數學中的數值表示是一樣的(注意點:數值不用加引號)
-
字串
- python 使用引號來表示字串(一串文字)
-
變數
- 什麼是變數:是用來儲存資料
- a = 100
- b = 200
- c = “ hello world”
- 變數名的命名規範:
- 只能包含數字、字母、下劃線,
- 不能以數字開頭,
- 不能有關鍵字( 注意點 )
- python 中所有的關鍵字: keyword.kwlist
- 儘量做到見名知意
- 儘量不要用拼音
- 什麼是變數:是用來儲存資料
-
識別符號:(凡是我們自己取的名字,都是識別符號。)
- 規範:識別符號由字母、數字、下劃線組成,不能使用關鍵字
- 識別符號包括:變數名、函式名、類名、模組名、專案名
- 在python中,所有識別符號可以包括英文,數字以及下劃線(_),但不能以數字開頭。
- python 中的識別符號是區分大小寫的,大寫的 A 和小寫的 a 不一樣
-
識別符號的命名風格:
- 下劃線命名法:
- 規範:單詞字母小寫,單詞之間使用下劃線連線
- 如:max_number ,test_data
- 大駝峰命名法:
- 規範:每個單詞的第一個字母大寫
- 如:MaxNumber , TestData
- 小駝峰命名法:
- 規範:第一個單詞以小寫字母開始,第二個單詞的首字母大寫
- 如:maxNumber , testData
- 下劃線命名法:
-
input 使用者輸入
- 從控制檯裡面獲取一個資料,獲取到的型別是字串型別
二、python中常見資料型別
(一)、數值型別 & 運算子
1、數值型別資料
- 數值型別
- 整數(int):整數
- 浮點數(float):小數
- 布林值(bool):只有兩個值 True 和 False
2、python 常見運算子
-
算術運算子:
- +
- -
- *
- /
- 除法運算一定要注意:除數不能為0
- 除數如果為0,就會報錯:ZeroDivisionError: division by zero
- //
- 整除
- %
- 餘數:模運算
# + print(5 + 6) # - print(7 - 8) # * print(2 * 3) # / # 只要是進行除法運算,得到的是一個 float print(4 / 3) print(4 / 2) # 除法運算一定要注意,除數不能為 0 # 除數如果為0,就會報錯:ZeroDivisionError: division by zero # 程式報錯以後,就無法繼續執行 # print(2/0) # print('hello world') # // 得到的是一個整數。 整除 print(4 // 3) # % 取餘數 : 模運算 print(4 % 3) # ** 冪運算 4的3次方 print(4 ** 3)
-
賦值運算子
- =
- +=
- -=
- *=
- /=
- //=
- %=
- **=
name = 'yuze' age = 18 #漲一歲 age = age + 1 print(age) #縮寫 age += 1 ==> age = age + 1 age += 2 print(age) age /= 3 print(age)
-
比較運算子: 比較運算得到的結果是一個 bool 值, True 或 False
- <
- >
- <=
- >=
- !=
> 大於 print(5 > 4) # True < 小於 print(6 < 3) # False >= 大於等於 print(6 >= 3) # True <= 小於等於 print(6 <= 3) # False != 不等於 print(6 != 3) # True TODO: == 才是比較運算, 一個 = 是賦值運算 print(6 == 6)
-
邏輯運算 : 可以使用()提高優先順序
- and
- or
- not
a = 3 > 4 print(a) b = 4 != 5 print(b) # 運算 and # 每一個都為 True print(a and b) # False # 運算 or # 只要有一個為 True print(a or b) # True # 練習 a = True b = 5 == 4 # False c = 5 != 3 # True print(a and b or c) # True print(a or b and c) # True # python 的運算有沒有優先順序,如何設定優先順序 # 使用 () 設定優先順序 print(((a and b) or c) and b) # not 取反 print(not(b)) # True
-
身份運算
- is
- is not
-
成員運算
- in
- not in
# in name = 'yuz' print('u' in name) # True print('uz' in name) # True print('uai' in name) # False # TODO: in 一定是連著的, yz 是一個整體 print('yz' in name) # False print('Y' in name) # False
3、隨機數模組: random (python 官方庫)
-
隨機生成 0-1 之間的浮點數:random.random()
-
隨機生成 0-100 之間的浮點數:random.randint(1, 100)
import random f_num = random.random() print(f_num) num = random.randint(0, 100) print(num)
(二)、字串
本節問題:
問題一:python中如何表示字母,比如要將一個人的名字儲存下來?
問題二:字串如何定義?
問題三:字串如果要換行怎麼辦?
問題四:數值型別的資料可以轉換成字串嗎?
問題五:可以把兩個字串組成一個嗎?
問題六;如何獲取字串中某個具體的字元?
1、字串的定義:
-
單引號、雙引號:定義單行字串
-
三引號、三雙引號: 多行字串定義
-
空字串: s=''
-
str():
-
注意點:字串中有單引號時,外面用雙引號注意區分
"""字串的定義 如何表示字串: - 引號表示字串 - 單引號 '' - 雙引號 "" - 三引號 ''' ''' - 三雙引號 """ """ """ name1 = "yuze" print(name1) name2 = 'yuze' print(name2) name3 = '''yuze''' print(name3) name4 = """yuze""" print(name4) print(name1 == name2 == name3 == name4) # True print(name1 == name2) # True print(name1 == name3) # True print(name1 == name4) # True
2、字串的切片和下標取值
-
1、下標索引取值
- 下標取值:可以正向取,也可以反向取
- 注意點:正向從 0 開始,反向從 -1 開始
name = 'yuzwang' print(name[1]) # u print(name[0]) # y # 獲取第3個字元 print(name[2]) # z # 獲取 g print(name[6]) print(name[-1])
-
2、切片: [:][::]
- 問題:下標取值只能獲取單個元素,現有字串 str1='hello python' ,如果要獲取出來 python 應該怎麼做?
- 切片的語法: 和下標取值一樣使用中括號進行切片,有兩種用法:
- [a:b] :a代表起始位置下標, b 代表終止位置下標(左閉右開);
- [a: b: c] : a代表起始位置下標, b 代表終止位置下標(左閉右開),c 代表步長。
"""字串的切片 slice 獲取多個字元 索引獲取的公式: m_str[start:end:step] 注意:end - start 的符號 必須和 step 的符號相同才可以獲取到索引 step 的值不能為0 """ name = 'yuzwang' # 要 1 和 2 print(name[1:2]) # u print(name[0:1]) # y # TODO: 這個才是對的 # TODO: 顧頭不顧腚,取頭不取尾,取左不取右 print(name[0:2]) # yu print(name[3:6]) # wan # 什麼是 step , 取完第一個索引,把索引 + 多少 # step = 2 print(name[3:6:2]) # wn print(name[1:5:3]) # ua # step 可以為負數 print(name[5:1:-3]) # nz print(name[5:1:3]) # 取不到值 None print(name[1:4:-2]) # 取不到值 None # TODO: end - start 的符號 必須和 step 的符號相同才可以獲取到索引 # TODO:step 的值不能為0,否則會報錯:ValueError: slice step cannot be zero print(name[1:5:0]) # TODO: IndexError print(name[1000000]) # IndexError: string index out of range print(name[1:1000000]) # uzwang 不會報錯,會取到所有值 name = "yuzewang" # 省略 end ,表示取到最後 print(name[1:]) # 省略 start ,表示從 0 開始 print(name[:5]) # 複製,copy 從頭到尾, # TODO: 面試題:複製字串 print(name[:]) name_copy = name[:] print(name_copy) # 倒序 '123456' ==> '654321' # TODO:面試題:倒序一個字串 print(name[::-1]) # gnawezuy
3、字串拼接和轉義
-
+ 號:'hello' + 'python'
-
字串轉義:
- \n: 換行符
- \t: 水平製表符
- 關閉轉義:r'hello \n python'
name = 'yuz' family_name = 'wang' print(name + family_name) print(name + ' ' + family_name) 字串和數字能不能相加 print('yuz' + 7) # 字串和數字不能直接相加,會報錯:TypeError: must be str, not int print('yuz' + str(7)) # yuz7 資料型別的轉化 print(int(name)) # 報錯:ValueError: invalid literal for int() with base 10: 'yuz' print(int('12')) # 12 print(bool(34)) # True bool 轉化,只要是非0,非空的就是True 字串換行 '\' 不會分開成兩行 name = "yuze ooasfjojo" \ "wefwllfjlj" print(name) # yuze ooasfjojowefwllfjlj # 三引號換行,得到多行資料 name = """yuze flaljlkfjlajl lsajllakj fjk sjljjfljladf aljfl """ print(name) # 單引號中 \n 表示換行 name = 'kaixina lajj\nlfljajljssfjdlk\njljajs' print(name)
4、字串常用方法
- join : 字串拼接
name = "qin er cai"
# 字串拼接
print(name + 'wang')
# 使用 join 拼接
print(name.join(['a','b','c'])) # aqin er caibqin er caic
# 時間 ['2020', '08', '03'] 用 / 連線起來
print('/'.join(['2020', '08', '03'])) # 2020/08/03
print('2020' + '/' + '08' + '/' + '03') # 2020/08/03
- find : 查詢元素的位置
# find:在字串當中查詢某個字元或者字串的位置
# 會得到索引
a = "wangyuze is coming"
print(a.find('e')) # 7
index = a.find('e')
print(index) # 7
# 如果找的有兩個呢? i,會得到第一個
print(a.find('i')) # 9
# 如果是一個子串呢? ng
print(a.find('ng')) # 2
# 如果找不到怎麼辦?會得到 -1 ,這是規定
print(a.find('isnot')) # -1
# 如果子串不在一起,也是找不到,返回 -1
print(a.find('wn')) # -1
# index 約等於 find
# 區別:index 找不到元素的時候,會報錯,find 找不到的時候返回-1
print(a.index('ng')) # 2
print(a.index('wn')) # ValueError: substring not found
- count : 查詢元素的個數
# count 統計某個字元出現的次數
m_str = 'foweofpweef'
print(m_str.count('o')) # 2
song = "我愛你,我喜歡你,我..."
print(song.count('我')) # 3
- replace : 替換字元
# replace 替換
song = "我愛你,我喜歡你,我..."
print(song.replace('你', 'ta')) # 我愛ta,我喜歡ta,我...
- split : 字串分割
# split 切分、切割 ==》 和 join 相反
time_string = '2020/08/03'
print(time_string.split('/')) # ['2020', '08', '03']
-
format : 格式化輸出
-
upper : 將字母大寫
# upper 所有字母都大寫
name = 'yuze'
print(name.upper()) # YUZE
- lower : 將字母小寫
# lower 所有字母都小寫
name = 'JECK'
print(name.lower()) # jeck
- strip : 去掉兩邊的特殊字元,如果什麼都不傳,就是去掉空格或者換行符
# strip 去掉兩邊的特殊字元,如果什麼都不傳,就是去掉空格或者換行符
name = ' yuze wang '
print(name.strip()) # yuze wang
print(name)
cp = "&雨澤&哈哈&"
print(cp.strip('&')) # 雨澤&哈哈
- len : 計算字串長度
# len 計算字串的長度
name = 'yuzewang '
print(len(name)) # 9
5、字串格式化輸出
-
format 格式化輸出
- format() 功能強大,該函式把字串當成一個模板,通過傳入的引數進行格式化,並且使用 {} 作為特殊字元代替 %
資料 格式 結果 描述 5.11111 {:.2f} 5.11 保留小數點後兩位 0.25 {:.2%} 25.00% 百分比格式 aa {:<10} aa 左對齊(寬度為10) aa {:^10} aa 中間對齊(寬度為10) - format 字串的格式化
``` # 現在需要列印下面的格式: ------------------- 借條 借款人:yuz 債權人:double king 金額:500 ------------------- loan_name = 'yuz' rich_man = 'double king' money = 500 # # 方法一: # print("---------------------") # print('借條') # print('借款人:' + loan_name) # print('債權人:' + rich_man) # print('金額:' + str(money)) # print('---------------------') # # # 方法二: # {} 表示佔坑符,佔位符 # 位置一定要匹配,不能亂填順序 # print(""" # ------------------- # 借條 # 借款人:{} # 債權人:{} # 金額:{:.2f} 萬 # ------------------- # """.format(loan_name, rich_man, money)) # # # # 方法三: # # f-string : python3.6 以後才支援 # print(f""" # ------------------- # 借條 # 借款人:{loan_name} # 債權人:{rich_man} # 金額:{money} 萬 # ------------------- # """)
-
傳統的格式化輸出 %
符號 描述 %s 格式化字串 %d 格式化整數 %f 格式化浮點數字,可指定小數點後的精度
(三)、列表和元組
1、列表
-
列表的定義
- 是一種資料型別,可以用來儲存多個資料
- 列表用 [ ] 來標識
- 列表內部的元素可以是任意型別的
- 列表是使用最頻繁的資料型別之一
-
列表的常見操作
-
下標取值(索引取值):獲取某一個元素
-
切片操作:獲取多個元素
- 有步長的切片過程:先根據起始位置和終止位置,將內容切出來,然後再根據步長分為若干部分,然後將每部分的第一個元素拿出來,得出結果。
-
修改元素的值:可以通過下標修改指定位置的元素。
# 5 個人,5個大佬 , 使用列表 big_boss = ['Demons', 'Go', 'EE', '上善若水', 'summer'] print(big_boss) # 元素可以是任意的資料型別 big_boss = ['Demons', 11, True, 33.33, 'summer'] print(big_boss) big_boss = ['Demons', 11, True, 33.33, ['a','b','c']] print(big_boss) big_boss = ['Demons', 11, True, 33.33, ['a','b',['yuz',True]]] print(big_boss) # 索引: 獲取索引為 0 的元素 print(big_boss[0]) # Demons print(big_boss[-1]) # ['a', 'b', ['yuz', True]] print(big_boss[-2]) # 33.33 print(big_boss[2]) # True # 獲取 a print(big_boss[-1][0]) # a last_one = big_boss[-1] print(last_one[0]) # a # 獲取 'yuz' print(big_boss[-1][-1][0]) # yuz # 切片 print(big_boss[:3]) # ['Demons', 11, True]
-
-
列表巢狀
-
列表中如果有多層巢狀,取值時需要一層一層的取值
lst = [ 'a', 'b', [1,2,3] ] print(lst[0]) # a print(lst[-1][1]) # 2
-
-
列表的方法
- 增:append 、insert 、 extend
- 刪:pop 、 remove
- 改:通過下標修改值
- 查:index 、 count
- 其他:reverse 、 sort
方法 描述 append 在列表的尾部加入一個元素 insert 在指定位置插入一個元素 extend 插入多個元素 pop 刪除一個元素(預設從列表尾部刪除,也可以指定下標進行刪除) remove 刪除指定的元素(從前往後找) index 查詢元素的位置,找到第一個就返回結果 count 統計元素的個數 sort 將列表的元素進行排序 reverse 將列表內元素反序(頭變為尾,尾變頭) # TODO:坑 dalaos = ['隨風'] new_dalao = dalaos.append('利己') print(dalaos) # ['隨風', '利己'] # append() 返回 None print(new_dalao) # None # 再新增多個,['一罐','本本','可愛','美雪'] 新增到最後 dalaos.extend(['一罐','本本','可愛','美雪']) print(dalaos) # TODO: 坑2 報錯:AttributeError: 'NoneType' object has no attribute 'append' new_dalao = dalaos.append('sfo').append('hello').append('sof') print(new_dalao) # 增加某個元素,修改的是原來的變數 lst lst = ['yuz', 'shanshan', 'rita'] lst.append('裴綸') print(lst) # ['yuz', 'shanshan', 'rita', '裴綸'] # insert 指定索引位置新增元素,不是獲取索引,不用[] lst.insert(1, '仙人球') print(lst) # ['yuz', '仙人球', 'shanshan', 'rita', '裴綸'] # extend 新增多個,可以合併 2 個列表 lst.extend(['tiger', 'f2']) print(lst) # ['yuz', '仙人球', 'shanshan', 'rita', '裴綸', 'tiger', 'f2'] lst = [1,2,3] lst.append(3) print(f"第一次嘗試{lst}") # 第一次嘗試[1, 2, 3, 3] # lst.extend(3) # print(f"第二次嘗試{lst}") # 報錯:TypeError: 'int' object is not iterable lst.extend([3]) print(f"第三次嘗試{lst}") # 第三次嘗試[1, 2, 3, 3, 3] a = [1,2,3] b = [4,5,6] # b 是作為一個整體,一個元素,新增到 a 當中 # a.append(b) # print(a) # [1, 2, 3, [4, 5, 6]] # b 是拆開裡面元素,作為多個元素,新增到 a 當中 a.extend(b) print(a) # [1, 2, 3, 4, 5, 6]
"""列表的刪除 - remove - delete - pop """ # remove: 在列表當中刪除指定的值 big_boss = ['糖', '木易', '均價'] big_boss.remove('木易') print(big_boss) # ['糖', '均價'] # delete 異類:儘量不要用 # del big_boss[0] # print(big_boss) # ['均價'] # pop 0 代表索引為 0 big_boss.pop(0) print(big_boss) # ['均價'] # 獲取索引為 0 的值 print(big_boss[0]) big_boss.append('木易') print(big_boss) # ['均價', '木易']
"""列表的修改 lst[0] = 1 """ lst = [1,2,3] lst[1] = 'a' print(lst) # [1, 'a', 3] lst[1],lst[2] = 'c', 'd' print(lst) # [1, 'c', 'd'] lst[1:] = 5,6 print(lst) # [1, 5, 6]
"""列表的方法 - index - count - sort - reverse - clear """ lst = [4,5,6,5] # # 統計 # print(lst.count(5)) # 2 # # # index 查詢得到第一次出現的索引值 # print(lst.index(5)) # 1 # # # sort 排序 # print(lst.sort()) # None # # lst.sort() # print(lst) # [4, 5, 5, 6] # # # # reverse 反向,倒序 , 相當於 [::-1] # lst.reverse() # print(lst) # [6, 5, 5, 4] # 反向排序 lst.sort(reverse=True) print(lst) # [6, 5, 5, 4] # clera 清除一個列表 lst.clear() print(lst) # []
2、元組
-
元組的定義:
- 元組定義在小括號中,元組內部的資料:它支援數字,字串甚至可以包含元組(即巢狀)
-
元組的常見操作
- 下標取值:元組內部的資料是有序的,可以通過下標獲取對應的元素
-
注意點
- t = () 空元組
- t = (1,) 只有一個資料的時候要注意加逗號
- 元組的值不可以修改,是屬於不可變資料
-
元組的方法
- count : 查詢元素的個數
- index :查詢元素下標
tuple_yuz = ('yuz','一罐',['閒人','七七','小驕傲']) # 修改的是元組的元素,元組的元素是列表 # tuple_yuz[2] = ['新列表'] # print(tuple_yuz) # 不能修改元組的元素 # 為什麼這裡可以改?? # 元組的不可變是相對的,不是說裡面所有的內容都完全不能變 # 只要看索引的前面是不是一個可變的型別 tuple_yuz[2][0] = ['新列表'] print(tuple_yuz) tuple_yuz = ('yuz','一罐',{'tuple':'yuze'}) # 索引前面是元組,代表我們要修改的是元組的元素,不可以 # tuple_yuz[2] = 'hello world' # tuple_yuz[2] 是字典,可變型別,可以直接修改 tuple_yuz[2]['name'] = 'hello world' print(tuple_yuz) # 索引前yuz是列表,可以改變 yuz = ['yuz','一罐',('四葉草','曉峰')] yuz[2] = 'hello' print(yuz) # yuz[2]是元組,不可變 yuz[2][1] = 'youxi'
tuple_demo = () print(tuple_demo) # TODO:坑 ,一個元素的元組表示,不是一個元組,而是去掉括號後的原始資料型別 # tuple_demo_2 = (1) # print(tuple_demo_2) # 如果想表示一個元素的元組,記得務必在元素後面加一個逗號 # tuple_demo_3 = (1,) # print(len(tuple_demo_3)) tuple_demo_4 = (1,3,4,5,5,) print(len(tuple_demo_4)) tuple_demo_5 = 1 print(tuple_demo_5) # 元組解包 family_name,name = ('wang','yuze') # family_name,name = ('wang','yuze','hello') # 值要一一對應,否則會報錯 print(family_name) print(name) a,b = 3,4 print(a) print(b) family_name,name,*other = ('wang','yuze','hello','world') print(family_name) print(name) print(*other)
3、字串、列表、元組總結
- 序列型別:
- 字串、列表、元組,統稱為序列型別資料(內部的元素是有順序的)
- 通用操作:
- 下標取值:
- 切片:
- 獲取元素總數: len()
(四)、字典和集合
- 問題:
- 使用一個列表儲存了一個學生資訊,姓名,年齡,電話號碼,stu = ['小明', '18', '13812341234']
- 問題一:當前如果電話號碼寫錯了,怎麼修改
- 問題二:當前列表中有10個設定100個元素,不知道電話號碼具體的下標,怎麼修改電話號碼
1、字典
-
字典的定義:
-
也是用來儲存多個資料的
-
字典:字典用 {} 來標識
-
字典能夠表示元素更具體的意思,每個元素表示的意義是什麼,可以通過 key 命名
-
字典的結構:就是將它看做是一個 {key:value} 鍵:值 對的集合,鍵必須是唯一的(在一個字典中)
-
空字典 : {}
-
字典定義的方式:
# 方式一: dic = {'name':'musen', 'age':18} # 方式二: dic = {name = 'musen', age = 18}
-
-
注意點:
- 字典中的鍵必須是唯一的
- key 不能出現重名,在一個字典當中,key 之間是不一樣的
- key 不能變的,列表是不能作為 key 的
- 可變型別資料:字典定義後可以修改內部元素
- 注意點:字典的鍵必須是不可變型別的(一般情況下都是字串),值可以是任意型別的資料(字典,元組,列表等等都可以)
-
字典的增刪改查
-
增
-
通過指定鍵去新增相應的值
dic[key] = value -
update() : 將一個字典的所有元素更新到另一個字典中
# 簡單理解 dic.update({'a':1, 'b':2})
-
-
改:通過指定鍵去修改對應的值
dic[key] = value -
刪
-
pop() : 刪除指定的鍵,刪除的鍵不存在會報錯(避免錯誤可以新增預設值)
dic.pop(key) -
popitem() : 刪除一個鍵值對,刪除最後一個新增的元素
- 之前版本是隨機刪除一個元素,python3.7新特性,刪除最後新增的元素
-
關鍵字 del : 通過鍵刪除
del dic[key]
-
-
-
查
- get() : 獲取鍵對應的值
- keys() : 獲取所有的鍵,可以用 list 將結果轉換成列表
- values() : 獲取所有的值,可以用 list 將結果轉換成列表
- items() : 獲取所有的鍵值對,可以用 list 將結果轉換成列表,列表中每個鍵值對組成一個元組。
# 列表:當每個元素有具體的意義,你又想去單獨獲取的時候,可讀性不強 beisheng = ['星際穿越', '蜘蛛俠', '上海堡壘', '分手大師', '前任3'] print(beisheng[2]) # 字典:key: 元素的名稱, value: 元素的值 , 鍵值對:成對 # 用 {} 在最外面 # key: value, key1: value1 beisheng = {'favor':'星際穿越','hate':'蜘蛛俠','first':'上海堡壘','last':'分手大師','twice':'前任3'} print(beisheng['hate']) # 蜘蛛俠 # 重名的key beisheng = {'favor':'星際穿越', 'hate':'蜘蛛俠', 'first':'上海堡壘', 'favor':'分手大師', 'twice':'前任3'} # favor 後面的值會覆蓋前面的值 print(beisheng['favor']) # 分手大師 print(beisheng) # {'favor': '分手大師', 'hate': '蜘蛛俠', 'first': '上海堡壘', 'twice': '前任3'} # key 不能是列表 # beisheng = {'favor':'星際穿越', # ['hate']:'蜘蛛俠', # 'first':'上海堡壘', # 'favor':'分手大師', # 'twice':'前任3'} # print(beisheng) # 報錯:TypeError: unhashable type: 'list' # 鍵為數字: 沒有意義,不建議使用 beisheng = {1:'星際穿越', 3:'蜘蛛俠', 2:'上海堡壘', 5:'分手大師', 4:'前任3'} print(beisheng) # {1: '星際穿越', 3: '蜘蛛俠', 2: '上海堡壘', 5: '分手大師', 4: '前任3'}
beisheng = {'favor':'星際穿越', 'hate':'蜘蛛俠', 'first':'上海堡壘', 'last':'分手大師', 'twice':'前任3'} # 獲取,查 print(beisheng['hate']) # 字典沒有索引和切片 # 修改 beisheng['hate'] = '蝙蝠俠' print(beisheng) # {'favor': '星際穿越', 'hate': '蝙蝠俠', 'first': '上海堡壘', 'last': '分手大師', 'twice': '前任3'} # 新增, 和修改是一樣的 # 什麼時候是修改,什麼時候又是新增? # 看 key:當 key 已經存在的時候,是修改,當之前沒有這個key,就是新增。 beisheng['scared'] = '貞子' print(beisheng) beisheng['scared'] = '午夜凶鈴' print(beisheng)
2、集合
-
定義:
- 集合中的元素不能重複
- 花括號 或 set() 函式可以用來建立集合
-
注意:
- 要建立一個空集合你只能用 set() 而不能用 {} ,因為後者是建立一個空字典
-
集合的方法:
- 增加元素 : add
- 刪除元素 :pop , remove
- 自動化測試中很少用集合來存放資料,更多內容請自行擴充套件
-
集合的重要應用場景:去重
-
集合的交集、並集、差集
- a & b : 集合 a 和 b 中都包含了的元素
- a | b : 集合 a 或 b 中包含的所有元素
- a - b : 集合 a 中包含而集合 b 中不包含的元素
# 集合不是鍵值對 # 集合是無序的 # 不能通過索引獲取 # 重複的元素直接丟掉,集合目前我們使用的最多的功能就是去重 set_yuz = {'yuz','魯西西','閒人','yiguan'} print(set_yuz) # print(set_yuz[1]) # 會報錯 print(len(set_yuz)) # 去重 set_yuz = list(set(['yuz','魯西西','閒人','yuz'])) print(set_yuz) # split 分割 # a = 'hello world' # b = a.split('w') # print(b) a = 'hello/world/sofo/sooof' b = a.split('/',1) # 數字1代表分割一次 print(a) # a 是字串,不會變 print(b)
(五)、資料型別相互轉換
1、字串的轉化
-
字串轉換成列表
- 字串轉換成list 的時候,str可以作為迭代物件,直接放入;也可以使用split對字串進行切割。然後返回list
s = '1ab1cd' print(list(s)) # ['1', 'a', 'b', '1', 'c', 'd'] print(s.split('1')) # ['', 'ab', 'cd']
-
字串轉換成元組
s = '1ab1cd' print(tuple(s)) # ('1', 'a', 'b', '1', 'c', 'd')
-
字串轉換成字典
a='1ab1cd' b='123456' print(zip(a,b)) # <zip object at 0x00000000022952C8> print(dict(zip(a,b))) # {'1': '4', 'a': '2', 'b': '3', 'c': '5', 'd': '6'} a='1ab1cdd4e5' b='123456' print(zip(a,b)) # <zip object at 0x00000000022952C8> print(dict(zip(a,b))) # {'1': '4', 'a': '2', 'b': '3', 'c': '5', 'd': '6'}
-
字串轉換成集合
a='1ab1cd1d' print(set(a)) # {'1', 'a', 'c', 'b', 'd'}
2、列表的轉化
-
列表轉換成字串
- 列表裡如果有int型別,字典,元祖,列表,則join方法不可用
list = ["3","d","aaa"] print("".join(list)) # 3daaa print(" ".join(list)) # 3 d aaa print("!".join(list)) # 3!d!aaa
-
列表轉換成元組
list = ['1','2','3','a',(1,2,3),1,[1,2],{"a":1}] print(tuple(list)) # ('1', '2', '3', 'a', (1, 2, 3), 1, [1, 2], {'a': 1})
-
列表轉換成字典
list1 = ['1','2','3','4','a',(1,2,3),5,6] list2 = ['a','b','c','d','e','f',[1,2],{"g":"h"}] dict1 = dict(zip(list1,list2)) print(dict1) # {'1': 'a', '2': 'b', '3': 'c', '4': 'd', 'a': 'e', (1, 2, 3): 'f', 5: [1, 2], 6: {'g': 'h'}}
-
列表轉換成集合
list = ['1','2','3','3'] print(set(list)) #{'3', '1', '2'}
3、元組的轉化
-
元組轉換成字串
- 元組裡如果有int型別,字典,元祖,列表,則join方法不可用
tuple = ('1','2','3','4','2','a') print(''.join(tuple)) # 12342a
-
元組轉換成列表
tuple = (1,2,3,4,5,'2','a') print(list(tuple)) # [1, 2, 3, 4, 5, '2', 'a']
-
元組轉換成字典
tuple1 = ('1', '2', '3', '4',111,(11,22,33),"") tuple2 = ('a', 'b', 'c', 'd','e','f','h','g','i','j','k') dict1 = dict(zip(tuple1, tuple2)) print(dict1) # {'1': 'a', '2': 'b', '3': 'c', '4': 'd', 111: 'e', (11, 22, 33): 'f', '': 'h'}
-
元組轉換成集合
tuple1 = ('1','2','3','4',4,'4',4,1) print(set(tuple1)) # {1, 4, '3', '1', '2', '4'}
4、字典的轉化
-
字典轉換成字串
- 對於生成字串,需要先生成list和tuple,然後再由list和tuple生成str
dict1 = {1:'a',2:'b',3:'c'} list1 = list(dict1.values()) print("".join(list1)) # abc tuple1 = tuple(dict1.values()) print("".join(tuple1)) # abc
-
字典轉換成列表/元組/集合
- 字典可以使用 dict.keys() 和 dict.values() 返回迭代器,通過list和tuple直接生成列表和元祖
dict1 = {1:'a',2:'b',3:'c'} print(list(dict1.keys())) # [1, 2, 3] print(list(dict1.values())) # ['a', 'b', 'c'] print(tuple(dict1.keys())) # (1, 2, 3) print(tuple(dict1.values())) # ('a', 'b', 'c') print(set(dict1.keys())) # {1, 2, 3} print(set(dict1.values())) # {'a', 'b', 'c'} print(tuple(dict1.items())) #生成元祖為單位的元祖 # ((1, 'a'), (2, 'b'), (3, 'c')) print(list(dict1.items())) #生成元祖為單位的列表 # [(1, 'a'), (2, 'b'), (3, 'c')] print(set(dict1.items())) #生成元祖為單位的集合 # {(2, 'b'), (3, 'c'), (1, 'a')}
5、集合的轉化
-
集合轉換成字串
- 集合是無序的,每次轉換成的字串值都不一定一樣,也可以先轉為列表或者元祖,再轉換成字串
set1 = {"1","2","ac"} print("".join(set1)) # 2ac1 print(type("".join(set1))) # <class 'str'>
-
集合轉換成列表/元組
set1 = {1,2,3,4,5,6} print(list(set1)) # [1, 2, 3, 4, 5, 6] print(tuple(set1)) # (1, 2, 3, 4, 5, 6)
-
集合轉換成字典
- 無意義的對映,不推薦
set1 = {1,2,3,4,5,6} set2 = {'a','b','c','d'} print(dict(zip(set1,set2))) # {1: 'd', 2: 'a', 3: 'b', 4: 'c'}
三、控制流程
(一)、條件語句
-
if條件判斷
- 分支結構,常用的表現方式:
- if(條件表示式):......
- if(條件表示式):......else:......
- if(條件表示式):......elif(條件表示式):......elif(條件表示式):......else:
- 分支結構,常用的表現方式:
# if的寫法(else可以省略)
if (條件表示式):
pass
else:
pass
if (條件表示式):
pass
elif (條件表示式):
pass
else:
pass
# 例如:
username = "yuze"
if username == "yuze" or username == "yuzewang":
#縮排表示條件滿足以後需要執行的子程式碼,是一個分支
print("登入成功")
elif username == ""
print("請輸入使用者名稱")
elif username == "Demo"
print("沒有該使用者")
else
print("登入失敗")
-
if語句用於驗證某個條件
- 當條件為真時,執行if下面的程式碼塊,否則執行else下面的程式碼塊
- 條件當中,只要執行了一個分支,其它分支就不會繼續執行了
- 條件表示式:要得到的值是一個bool型別,True, False
-
使用if需要注意的點
- 所有分支流必須以if開頭
- 語句中的else可以省略
- if與elif後面必須加條件表示式,else後面不能加條件表示式
- 一個判斷分支下只有一個if,一個else,可以有多個elif
- 分支下按順序執行程式碼,只要執行了一個分支下的程式碼,其他的分支則都不會執行
(二)、程式debug除錯
- 是暫停程式碼的執行去獲取現在的資料狀態
- pycharm中的debug
- 先打斷點
- 再執行debug
- 下一步按鈕
- 檢視資料
- 打斷點,是告訴程式我應該在哪裡暫停
(三)、while迴圈
-
迴圈控制流
- 迴圈語句,用於驗證某個條件
- 當條件為真時,執行迴圈下的程式碼塊,否則結束迴圈
- 分類:
- while 迴圈
- for 迴圈
-
while迴圈作用:用來重複執行某個操作
-
while 語法
while 判斷條件:
執行程式碼
# 例如:
times = 0
while times < 999:
print("我說了{times}次")
times = times + 1
continue: 表示手工進入下一個迴圈體,進入下次迴圈
break:表示手工強制退出整個while迴圈
(四)、for迴圈
-
作用:
- 用來遍歷物件
- 從物件的第一個元素到最後一個元素,依次訪問
- for迴圈會自動+1
-
語法
- for 元素 in 資料集合:執行程式碼
- 資料集合可以是:列表,元組,字典,字串,也可以是指定的資料範圍
- for迴圈巢狀,子迴圈執行完,才會回到母迴圈執行
for 迭代變數 in 字串|列表|元組|字典|集合:
程式碼塊
# 例如:
add = "http://c.biancheng.net/python/"
#for迴圈,遍歷 add 字串
for ch in add:
print(ch,end="")
continue:手工進入下一個迴圈體,進入下次迴圈
break:手工強制退出整個while迴圈
-
break
- 常用在迴圈結構中
- 在迴圈中遇到break,就跳出迴圈
-
continue
-
常用在迴圈結構中
-
在迴圈中遇到continue,就跳出本次迴圈,繼續下一次迴圈
(五)總結知識點
- for經常用到的場景:如果有一個現成的列表,字串,字典,就用for
- while經常用到的場景:不知道什麼時候結束迴圈
- 同時獲取列表的索引和值
for i,value in enumerate(list):
print(i, value)
- 同時獲取字典的鍵和值(常用)
for k,v in mdict.items():
print(k, v)
- 獲取所有的value
for value in mdict.values():
print(value)
- 獲取所有的key
for key in mdict.keys():
print(key)
for k in mdict:
print(k)
-
range() 函式
- 表示迴圈某一個資料段
- range(start,end,step),與切片類似,包前不包後
- 列印100遍
for i in range(100): print(i)
四、函式和函式引數
(一)、函式定義和呼叫
1、函式的定義
-
函式的概念:以數學函式來理解
-
作用:傳入一個自變數,會得到一個另外的變數,這個變數會根據自變數變化而變化
-
用於儲存一段程式碼。 是封裝
-
定義函式關鍵字:def
-
為什麼要寫函式:方便好用、複用性高
-
函式名:屬於識別符號,遵循識別符號的命名規則:
- 函式的名稱是一個識別符號:數字、字母、下劃線,不能是內建關鍵字
- 函式名遵循蛇形命名:下劃線命名
- 函式名稱要見名知義
- 函式命名的重要性:函式的名稱會告訴讀程式碼的人:這個函式的作用是什麼
-
語法:
def 函式名(引數): 函式內部功能程式碼一 函式內部功能程式碼二 函式內部功能程式碼三 函式內部功能程式碼四 def add(a,b): print(a+b)
-
函式中的程式碼如何執行?
- 函式定義時,函式的程式碼不會被執行,只有當函式被呼叫時,函式中的程式碼才會被執行
-
不要在一個檔案中定義兩個同名函式,後面的會覆蓋前面的
def add (a,b):
print(a+b)
def add (a,b):
print(a-b)
add(1,2) # -1
2、函式的呼叫
-
使用函式的過程叫做呼叫函式;呼叫的時候會給變數賦值,即變數 = 值
-
呼叫方法:
函式名()
-
函式的相互呼叫
- 在函式中呼叫另外一個函式
- 函式呼叫是去執行函式體內部邏輯
- 避免兩個函式相互呼叫
- 不要呼叫自己
(二)、函式的返回值
- return 的作用:
- 返回值數目 = 0;返回 None
- 返回值數目 = 1:返回object
- 返回值數目 > 1:返回tuple
- 疑問:為什麼要用return?什麼時候用return?
- 根據需求,當需要返回的時候就返回,不需要返回的時候就不返回。
- 注意點:
- 1、return 是用來給函式返回結果的。
- 2、當函式執行到return 時函式執行結束。
- 3、函式沒有定義return,預設的返回值為None
- 現在有兩件事,寫成兩個函式
(三)、函式引數
-
1、引數的定義
- 函式名後面的括號彙總定義引數
-
2、形參與實參
- 在函式定義的時候出現,是變數名,是自己定義的
- 呼叫時實際傳遞的引數為:實參,是函式呼叫時出現的,實際引數是將要賦給變數名(形參)的值
- 實參和形參要配對,成對出現的,下面情況都是不行的
- 只有實參,沒有形參
- 只有形參,沒有實參
def add (a,b): print(a+b) return(a+b) add(1,2) # a,b是形參, 1,2 是實參
-
位置引數
- 函式的形參和實參是成對出現的,一一對應的
- 函式呼叫的時候一定要檢查好引數的個數
- 位置引數概念
- 形參和實參的這種位置關係叫位置引數
def add (a,b): print(a+b) return(a+b) add(1,2) # 1對應a, 2對應b
-
關鍵字引數
- 關鍵字引數,函式呼叫的時候,給實際引數貼標記,標記是形參的變數名
- 通過關鍵字引數,可以不按順序配對
- 關鍵字引數要放在位置引數的後面
- 關鍵字引數的作用:當引數很多時,可以使用
def add (a,b): print(a+b) return(a+b) add(b=3,a=2)
-
預設引數
- 在函式定義的時候,給形式引數一個預設的值
- 呼叫函式的時候,可以不用賦值給預設引數
- 使用預設引數:可以少些實際引數
- 放在位置引數後面
def add (a,b=8): print(a+b) return(a+b)
-
不定長引數
- 不定長參數列示方式: * **
- * 當在一個形參前加*,他會收集所有剩下沒有配對的實際引數(位置引數),把剩下的資料組成一個元組
- *args 存放很多位置引數
def add (a,*b): print(a) print(b) add(1,2,3,4) # 1,(2,3,4) def add (a,*b): print(a) print(b) add(1,2,3,4,c=1) #報錯:預設引數要放到位置引數後面,不定長引數放到位置引數後面
-
**只能收集關鍵字引數
-
**kwargs 存放很多關鍵字引數
-
將資料轉換為字典的形式
def add (a,**b):
print(a)
print(b)
add(1,c=1,d=2) # 1 {'c': 1, 'd': 2}
-
不定長引數的作用
- 在引數定義的時候,不知道有多少個實際引數(關鍵字引數)
-
拆包:
- 列表、元組拆包
- 會拆成位置引數
- 函式定義當中args 表示不定長的位置引數,在呼叫的時候,叫做拆包、解包
- 呼叫的時候,把 一個列表或元素變數傳入函式,在前面加,就可以比那成多個值
def marry(male,female): print(male) print(female) couple = ("老王","小星星") marry(*couple)
- 字典拆包
- 會拆成關鍵字引數
couple = {"male":"小王","female":"老劉"} marry(**couple)
- 列表、元組拆包
(四)、函式作用域
- 是區域性作用域
- 在定義函式時,設定的變數為區域性變數
- 區域性變數不能在全域性作用域獲取
- 函式內部區域性作用域可以用全域性變數
- 在函式外部不能修改函式內部的變數
- 在函式內部可以修改全域性變數,不過需要用global宣告是全域性變數 例如:global c
(五)、內建函式
-
print :輸出
-
input :輸入
-
type :檢視資料型別
-
range :生成資料
-
id :獲取資料記憶體地址
-
int、float、str、bool、list、dict、tuple、set :代表對應的資料型別,轉換資料型別
-
max :獲取最大的值,可以傳多個引數,可以傳列表
-
min :獲取最小的值,可以傳多個引數,可以傳列表
-
sum :求和
-
enumetate:
# enumerate() 將列表中的元素及其位置轉換為成對的元組 m_list = ['aa', 'bb', 'cc', 'dd'] print(list(enumerate(m_list))) # [(0, 'aa'), (1, 'bb'), (2, 'cc'), (3, 'dd')] print(list(enumerate(m_list, start = 1))) # [(1, 'aa'), (2, 'bb'), (3, 'cc'), (4, 'dd')]
-
eval :可以去掉一個字串的引號
m_str = "6>7" print(m_str) print(eval(m_str)) # False m_str = '{"username":"yuz","age":18}' print(m_str) # {"username":"yuz","age":18} print(type(m_str)) # <class 'str'> print(eval(m_str)) # {'username': 'yuz', 'age': 18} print(type(eval(m_str))) # <class 'dict'>
-
filter :過濾某些資料 filter(呼叫函式,列表)
li = [2,3,4,5,6,7]
def get_odd(value):
if value % 2 == 0:
return True
return False
res = filter(get_odd, li)
print(list(res)) # [2, 4, 6]
- map :
li = [2,3,4,5,6,7]
def square(value):
return value ** 2
res = map(square, li)
print(list(res)) # [4, 9, 16, 25, 36, 49]
- zip :
li_1 = ["yuz","hello","world"]
li_2 = [43,12,15]
print(list(zip(li1,li2))) # [('yuz', 43), ('hello', 12), ('world', 15)]
a = zip(li1, li2)
print(dict(a)) # {'yuz': 43, 'hello': 12, 'world': 15}
(六)、模組和包
-
模組
- 模組,就是一個帶 .py 字尾的python 檔案,一個模組裡面會有很多的函式,類
- 模組名稱:是一個識別符號,符號識別符號命名規則
- 數字、字母、下劃線,不能以數字開頭,不能是關鍵字
- 模組名稱命名一般是使用下劃線的形式命名,駝峰, d1_review.py
- 模組名稱不能和 python 內建的模組名稱重合
- 模組作用:
- 有邏輯的組織python程式碼
- 把相關功能的程式碼寫到一個模組裡能讓程式碼更好用,更易懂
-
包
- 包,package,就是一個python檔案的資料夾,裡面會有一個或多個模組
- 包含一個_init_.py 模組的資料夾,這個模組可以什麼都不定義,可以只是一個空資料夾
- 標準庫,第三方庫,實現特定功能的程式碼集合,一個模組,也可以是一個包
- python3 新版本,不帶_init_.py 同樣可以作為包使用
-
模組匯入
-
是模組間變數和函式的互相使用 ,需要使用 import 的關鍵字
-
import ... 後面只能跟 模組,不能跟函式,變數
-
from .. import ... 後面可以跟模組,函式,類,變數
-
匯入自己的模組,別人的第三方模組,一般使用from import ,不用import..
-
google內部約定,匯入模組只匯入模組這一層,然後使用 模組名.函式名() 來呼叫函式
from class_9_file import demo01 demo01.test01_fun()
-
import .. 呼叫函式的時候需要些很長的字首,比較麻煩
-
-
不建議使用:from... import *
- 匯入模組或者包裡面,所有的類、函式、變數
- 匯入所有,如果重命沒有解決方法
-
as 重新命名 - 避免同名函式衝突
-
匯入時匯入到模組這一層,使用時使用模組名.函式名
-
使用別名
- 別名就是重新命名,就是原函式名很長,為了方便使用函式
from class_9_file import demo01 as d d.test01_fun()
-
-
不要用相對匯入,要絕對匯入,就是從根目錄開始匯入
-
五、檔案及路徑
(一)、檔案
1、開啟檔案和關閉檔案
-
開啟檔案,使用內建函式 open()
- open(" path/檔名.字尾 “)
-
特別注意:開啟檔案不管進行什麼操作後,一定要關閉檔案,否則會出現資料不對,或者寫入內容不生效,檔案無法再次被開啟等情況
f = open("python32.txt") f.close()
-
為了避免忘記關閉檔案,可以使用with語句,操作完成後會自動關閉檔案
with open('python32.txt','r',encoding='utf8') as f: print(f.read()) with open('python32.txt','a',encoding='utf8') as f: print(f.write())
-
不在同一路徑下要用絕對路徑,windows要加 r 防止轉義,有反斜槓,mac不用加
with open(r'J:\學習資料\Study\PythonAndSelenium\檸檬班python自動化課程\python32_API\class_09_file\python32.txt') as f: print(f.readline())
2、讀取檔案
-
mode 開啟方式
- r 以只讀方式開啟檔案(預設),一般用於文字檔案,如:txt。檔案指標預設放在檔案開頭
- b 以二進位制格式開啟檔案。一般用於非文字檔案,如:圖片、視訊
- rb 以二進位制的形式開啟並讀取
-
read() 讀取
with open("python32.txt", mode = 'r', encoding = 'utf8') as f: print(f.read()) with open('1.png', mode= 'rb') as f: print(f.read())
-
readline() 讀取一行
with open('python32.txt', encoding = 'utf8') as f: print(f.readline())
-
readlines() 讀取所有行,會以列表的形式展示
with open('log.txt', encoding = 'utf8') as f: print(f.readlines()) # 可以顯示換行符
3、寫入檔案
-
mode 寫入方式
- w 新建寫入
- w比較危險,如果之前已經有同名的檔案,用w會覆蓋之前的內容,w只能用於新建寫入
- a 追加寫入
- 如果檔名不存在,是先新建再寫入;如果檔名存在,則為追加
- wb 以二進位制開啟一個檔案用於只寫
- 如果檔名存在,則覆蓋,不存在,則新建寫入
- ab 以二進位制開啟一個檔案用於追加
- 如果檔案存在,檔案指標會放在檔案結尾處
with open('python32.txt', mode = 'w', encoding = 'utf8') as f: f.write('裴綸') with open('python32.txt', mode = 'a', encoding = 'utf8') as f: f.write('哈哈哈')
- + 表示可以同時讀寫某個檔案
- r+ 可讀,可寫
- w+ 可讀,可寫
- a+ 可讀,可寫
- w 新建寫入
(二)、路徑
1、路徑
-
sys . path 包含專案開始根目錄路徑和 python 內建的目錄路徑
- 模組匯入的搜尋路徑: sys.path
- 模組匯入不了時可以用來檢查
- python去查詢包或模組,相當於python裡的地圖
- 返回的是一個列表
- 模組匯入的搜尋路徑: sys.path
-
os 是 python 內建的模組需要用 import 匯入: import os
-
找模組
- 專案開始根目錄
- python內建目錄
- 不建議將寫的模組存放在python的安裝目錄下
- python目錄主要是放外部的庫或第三方的模組
2、路徑處理
-
python中一般不直接寫入絕對路徑, 而是通過程式碼獲取
-
獲取當前檔案的路徑:
abs_path = os.path.abspath(_file_)
_file_ 表示執行的檔案的名稱
-
獲取當前檔案的目錄路徑: 兩種寫法,用第一種絕對路徑
dir_name = os.path.dirname(abs_name)
dir_name = os.path.dirname(_file_)
-
獲取不與當前檔案同一個目錄下的檔案路徑
- 1 .先獲取當前檔案的絕對路徑
- 2 .獲取當前檔案的目錄路徑
- 3 .當前檔案的目錄路徑和該檔案拼接
比如,獲取pac01 下面的 demo.txt: txt_file_path = os.path.join(dirname, 'pac01', 'demo.txt') 讀取圖片檔案(二進位制格式) dir_name = os.path.dirname(os.path.abspath(file)) png_pic = os.path.join(dir_name,'1.png') f = open(png_pic,mode='rb') print(f.read()) f.close()
3、路徑操作
-
os.path.abspath() 獲取絕對路徑
-
os.path.dirname() 獲取檔案/目錄所在路徑
-
os.path.join(a, b) 連線兩個部分的路徑,組成一個完整路徑
-
os.getcwd() 獲取當前工作路徑
-
os.chdir() 切換工作路徑
-
os.mkdir() 在某個目錄下建立一個新目錄
-
os.rmdir() 刪除一個目錄
-
os.listdir() 獲取當前路徑下的目錄,返回列表格式資料
-
os.path.isdir() 判斷當前檔案是否是目錄,返回布林值
-
os.path.isfile() 判斷當前檔案是否是檔案,返回布林值
六、異常
(一)、異常處理
- 異常
- 當程式執行中檢測到一個錯誤時,無法繼續執行,出現一些錯誤提示,這就是異常。
- 程式遇到異常不會再執行,我們要改變程式碰到異常的行為
(二)、異常型別的捕獲
-
語法一:try...except....
-
程式先執行try中的程式碼,一旦try中某個程式碼報錯, 會直接跳到except,try剩下的程式碼不會執行
try: 要執行的可能發生異常的程式碼 except: 程式發生異常後,你希望程式做的事情 try: 1/0 except IndexError as e: print(e) # 其中as e可以在後面用來展示異常資訊,但不能展示異常型別
-
-
語法二:try...except....finally
try: 1/0 except ZeroDivisionError as e: print("不能除以0") finally: print("無論異常與否,都會繼續執行的程式碼") # 執行結果: # 不能除以0 # 無論異常與否,都會繼續執行的程式碼
-
try...except...else
try:
1 / 0
print("正常執行的程式碼")
except ZeroDivisionError as e:
print("不能除以0")
else:
print("程式碼沒有報錯才會執行")
print("正常執行的程式碼的後面部分")
# 執行結果:
# 不能除以0
(三)、多異常型別的捕獲
- 多種異常出現時,可以統一處理的就用下面的方式一,處理方式不一樣的就用方式二
方式一:
try:
{'name':'yez'}['age']
a = 1/0
lst = ['yz','yr']
lst[3]
except(ZeroDivisionError, IndexError, KeyError) as err:
print(err)
print('hello')
except ImportError as e:
print()
方式二:
try:
{'name':'yez'}['age']
a = 1/0
lst = ['yz','yr']
lst[3]
except ZeroDivisionError as err:
print(err)
except IndexError as err:
print('index error')
except KeyError:
print('key error')
(四)、丟擲異常
-
raise 主動丟擲異常
def adult_add(a, b): # 兩個數相加, a, b 一定要大於18, 否則就不能執行 if (a < 18) or (b < 18): raise ValueError('引數必須大於18') c = a + b return c print(adult_add(3, 4)) print('函式執行完成。') # 上面一行報錯,這行不會打 try: adult_add(3, 4) except: print('函式執行完成。') # 結果會列印:函式執行完成。
(五)、斷言 assert
-
斷言: assert
-
斷言的作用:判斷真假
-
斷言的時候,如果斷言成功,程式繼續執行
-
如果斷言失敗,程式終止執行,本質上斷言失敗會觸發一個異常型別:AssertionError
-
斷言,主要用在預期結果和實際結果的比對
height = int(input('輸入身高:')) print(height > 180) # False assert height > 180 print("斷言有結果")
七、物件導向
(一)、類(Class)
-
什麼是類:
- 是指所有符合某種特徵的個體的集合
- 類(Class) 是用來描述具有相同的屬性和方法的物件的集合。它定義了該集合中每個物件所共有的屬性和方法。
-
類的表示:(下面三種寫法作用完全一樣)
class 類名稱: # 類當中的內容 屬性 ==》 特徵 行為 class 類名稱(): pass class 類名稱(object): pass
class Dog: # 類內容 tailed = True def say(self): print('汪汪。。。')
-
類的命名
- 符合識別符號命名規則
- 字母數字下劃線,不能是關鍵字,要有意義
- 規範:大駝峰,SingleDog
-
使用 類 的好處
- 方便複用(如果你用函式寫,就要複製整塊程式碼,增加了程式碼量,增加了出錯率)
- 方便擴充套件(函式寫段程式碼,若要升級、擴充套件,都十分複雜,容易出錯,用類來擴充套件,則方便清晰)
- 方便維護(因為類是把抽象的東西對映成我們常見的,摸得到的東西,容易理解,維護也方便)
(二)、物件
-
什麼是物件:
- 物件指的是某個類當中的一個成員,一個個體
- 物件是從類當中生成的, ==》 類是一個模型,是一個生產圖紙。
- 物件就是類的具體例項
- 類是函式的定義,物件是函式的呼叫
- 例項、物件、object 都是同一個東西
class Dog: # 類內容 tailed = True def say(self): print('汪汪。。。') zhonghua = Dog() print(zhonghua) # 是物件 <__main__.Dog object at 0x00000000022724A8> print(Dog) # 是類 <class '__main__.Dog'> # Dog 不加括號的時候是類 zhonghua = Dog print(zhonghua) # <class '__main__.Dog'>
(三)、屬性和方法
- 屬性就是指類或者物件的特徵。名詞
- 方法就是指類或者物件的行為。動詞
- 屬性:
- 類屬性(類變數):類當中每一個成員都具備的特徵,類和物件都可以獲取類屬性
- 例項屬性(例項變數)、物件屬性:類當中的成員不一定都具備的特徵,是物件獨有的,自己具備
- 方法:
-
類方法:每一個成員或者整個類都能呼叫的行為
-
例項方法、物件方法:只能是需要一個單獨的成員呼叫的行為,不能是整個類呼叫
- 不要用整個類去呼叫例項方法
- 例項方法在定義的時候自帶一個引數:self,
- 但是例項方法在呼叫的時候不需要傳 self 這個引數的實際引數
class Dog: # 有尾巴 # 類屬性 tailed = True # 例項方法 def say(self): print('汪汪汪。。。') # 物件 teddy = Dog() # 類屬性的獲取 print(Dog.tailed) # True # 物件獲取屬性 print(teddy.tailed) # True # 屬性可以後天修改 Dog.tailed = False print(Dog.tailed) # False print(teddy.tailed) # False teddy.tailed = '有時候有尾巴,有時候沒有' print(Dog.tailed) # False print(teddy.tailed) # 有時候有尾巴,有時候沒有 # 類方法的呼叫 # Dog.say() # 會報錯 # Dog.say('abc') # 不要用整個類去呼叫例項方法 # teddy.say('abc') # 會報錯 teddy.say() # 汪汪汪。。。
-
(四)、物件的初始化
-
一個物件:除了整個類都具備的屬性,還有自己的特徵。 物件自己的特徵就叫例項屬性或者物件屬性。
-
每個物件都有自己不同的例項屬性,可以在物件生成的時候傳入實際引數,這個實際引數就是例項屬性,傳入實際引數時需要有對應的形式引數,這些形式引數不能在類後面直接定義,這裡就定義了一個特別函式,方法,_init_,在這裡面定義好的形式引數,最終在物件初始化的時候傳入實際引數,這個例項屬性產生的過程就叫物件的初始化。
-
傳入的實際引數是在什麼時候呼叫的???
teddy = Dog(name = 'teddy', color = 'blue') 自動呼叫 _init_
不需要寫 Dog._init_()TODO: 一定不要寫成 _int_
class Dog: tailed = True # 定義一個特別函式,方法,定義好的形式引數,最終在物件初始化的時候傳入實際引數 def __init__(self, name, color): """初始化函式,初始化方法""" # 自定義物件產生的過程 # 例項屬性的產生 self.name 定義一個叫做 name 的例項屬性 self.name = name self.color = color def say(self): print('汪汪汪。。。') teddy = Dog(name = 'teddy', color = 'blue') teddy.say() # 獲取例項屬性 print(teddy.color) # 類不能呼叫例項屬性 # print(Dog.color) # AttributeError: type object 'Dog' has no attribute 'color'
-
例項化
-
通過一個類去建立一個物件,就是例項化。
-
例項化是產生物件的過程
-
例項化就是函式的呼叫
-
產生物件,例項化物件的時候,會自動呼叫 _init_ 這個方法
self.name = name
self.name ==> 例項屬性
name ====> 引數, teddy 值。
name 這個name是變數,和類和物件沒有關係
-
-
什麼是 self :
-
所謂的self,可以理解為自己,就是我們的例項本身,代表例項物件,誰去呼叫代表誰。
Kitty 這個例項物件呼叫,self就代表Kitty
jingel 這個例項物件去呼叫,self就代表jingel
-
某個物件呼叫其方法時,python直譯器會把這個物件作為第一個引數傳遞給 self,只需要傳遞後面的引數即可
-
self 可以改成其他名字,但不建議改,你改了別人就不知道具體的含義了
class Dog: tailed = True # 定義一個特別函式,方法,定義好的形式引數,最終在物件初始化的時候傳入實際引數 def __init__(self, name, color='grey'): """初始化函式,初始化方法""" # 自定義物件產生的過程 # 例項屬性的產生 self.name 定義一個叫做 name 的例項屬性 # dog.name = name # 不能這樣寫,函式裡面不能使用全域性變數,這個時候 dog 這個物件還沒有產生出來 # Dog.name = name # 也不能這麼寫,不能所有的狗都叫同一個名字 self.name = name self.color = color print(self) def say(self): print('汪汪汪。。。') dog = Dog('teddy') print(dog.color) # grey # dog print(dog) # self 和 dog 物件是同一個地址 # ha = Dog('teddy') # print(ha.color) # grey # # dog # print(ha) # self 和 ha 物件是同一個地址
-
(五)、例項方法、類方法、靜態方法
1、例項方法:
- 定義:
- 例項方法直接定義在類中
- 第一個引數是 self (必須要寫),
- 例項方法的訪問
- 只有該類的例項物件都可以訪問,訪問例項方法的時候會自動將物件本身當成引數,傳給self接收
- 在類和物件當中,例項方法是用的最多的。
- 如果不知道該定義成例項方法,類方法還是靜態方法,就定義成例項方法
- 呼叫方法:
- obj.方法名()
- 例項.方法()
2、類方法:
-
定義:
使用裝飾器 @classmethod。第一個引數必須是當前類物件,該引數名一般約定為“cls”,通過它來傳遞類的屬性和方法(不能傳例項的屬性和方法)
-
呼叫:
- 例項物件和類物件都可以呼叫
-
應用場景:
- 需要站在類的角度執行某個行為時,那麼就應該定義為類方法
-
類方法呼叫
- 類.類方法()
3、靜態方法:
-
定義:
- 使用裝飾器 @staticmethod 引數隨意,沒有 self 和 cls 引數,但是方法體中不能使用類或例項的任何屬性和方法
-
呼叫:
- 例項物件和類物件都可以呼叫。
-
應用場景:
- 存放邏輯程式碼,內部不需要引用類屬性和例項屬性
- 當想在一個類當中定義一個方法,和這個類或者物件沒有直接的關係。
- 你在方法當中,沒有使用到類或者是物件。
-
靜態方法呼叫:
- 類和物件,都可以呼叫靜態方法
-
靜態方法存在的理由:
- 放在類裡面方便管理
def say_static(times): # 放在這裡是普通的函式,和放在類裡面效果是一樣的,只是呼叫時這個直接呼叫,呼叫類裡面的需要加字首
print(f'汪汪。。。{times} 聲')
class Dog:
tailed = True
# 定義一個特別函式,方法,定義好的形式引數,最終在物件初始化的時候傳入實際引數
def __init__(self, name, color='grey'):
"""初始化函式,初始化方法"""
self.name = name
self.color = color
print(self)
# 例項方法
def say(self, times):
print(f'{self}汪汪汪。。。{times} 聲')
# 靜態方法
@staticmethod
def say_static(times):
print(f'汪汪汪。。。{times} 聲')
# # 類方法。進化
# def jinhua(self):
# print('狗類正在進化')
# Dog.tailed = False
# 宣告:這是一個類方法
# 固定寫法
@classmethod
def jinhua(cls):
print('狗類正在進化')
Dog.tailed = False
haha = Dog('haha')
yiyi = Dog('yiyi')
# print(haha.tailed) # F
# print(yiyi.tailed) # F
# Dog.jinhua() # jinhua()是例項方法,不能使用類去呼叫
# print(haha.tailed)
# print(yiyi.tailed)
# 類方法的呼叫
# Dog.jinhua() # Dog 加括號表示物件,不加括號表示類
# haha.tailed
# haha.jinhua()
# print(haha.tailed)
#
# haha.say(5)
# 靜態方法的呼叫,類和物件,都可以呼叫靜態方法
haha.say_static(5)
Dog.say_static(6)
# 普通函式版
say_static(7)
(六)、繼承
(1)、類的繼承
-
定義類兩種方式的區別:
# Python2 中稱為經典類,在python3 中預設繼承 object class MyTest: pass # python2 中稱為新式類。 class MyTest(object): pass # 注意點:python3 中上面兩種定義方法沒有區別,都是繼承 object 這個父類
-
在python3 的繼承中,所有的類都預設繼承自 object 這個基類。
-
子類通過繼承可以獲得父類的屬性和方法。
-
被繼承的類叫父類(也叫基類),繼承的類叫子類
-
注意:私有屬性不能繼承
-
作用:
- 子類通過繼承可以獲得父類的屬性和方法,提高開發的效率及程式碼的複用率
# 普通寫法定義手機類和智慧手機類 class Mobile: def __init__(self, model, color='blacd'): self.model = model self.color = color def call(self): """打電話""" print(f"{self} 手機正在打電話。") class SmartPhone: def __init__(self, model, color='blacd'): self.model = model self.color = color def call(self): """打電話""" print(f"{self} 手機正在打電話。") def play_game(self): print("玩遊戲") # 使用繼承 class Mobile(): def __init__(self, brand, model, color='blacd'): self.model = model self.color = color self.brand = brand def call(self): """打電話""" print(f"{self} 手機正在打電話。") class SmartPhone(Mobile): def play_game(self): print("玩遊戲") # iphone = SmartPhone() # iphone.play_game() # 這裡會報錯,初始化的時候需要呼叫__init__方法,自己沒有去找父類,父類的__init__需要傳引數 iphone = SmartPhone('iphone12', 'apple') iphone.play_game()
(2)、超繼承
-
重寫父類方法
- 重寫,就是子類中,有一個和父類相同名字的方法,在子類中的方法會覆蓋掉父類中的同名方法
- 如:同樣是打電話,第一版手機只能大語音電話,最新版手機可以打視訊電話
-
呼叫重名的父類方法
- 子類重寫了父類的方法之後,如何在子類中再呼叫父類的方法:
- 方式一:父類名.方法名(self)
- 方式二:super().方法名()
class Mobile(): def __init__(self, brand, model, color='blacd'): self.model = model self.color = color self.brand = brand def call(self): """打電話""" print(f"{self} 手機正在打電話。") class SmartPhone(Mobile): def __init__(self, model, brand, color='red', pixel = 2000): # self.model = model # self.color = color # self.brand = brand # 這三行程式碼父類中有,可以使用 super() super().__init__(brand, model, color) # 使用 super() 直接呼叫父類的方法 self.fiveG = True self.pixel = pixel def play_game(self): print("玩遊戲") def call(self): """智慧手機打電話""" print('開視訊') super().call() # super 函式的使用 smart = SmartPhone('p40','huawei') print(smart.pixel) smart.call()
- 子類重寫了父類的方法之後,如何在子類中再呼叫父類的方法:
(七)、動態獲取屬性
-
獲取物件屬性的時候,如果物件中沒有這個屬性,程式碼就會報錯
-
可以使用 getattr( 物件, 屬性名稱 , 預設值) 動態獲取屬性,並在屬性後面傳入一個預設值,如果物件沒有這個屬性就會顯示預設值,程式碼就不會報錯
-
還可以動態修改屬性,使用 setattr( 物件, 屬性名稱 , 屬性值)
class Mobile: def __init__(self, brand, model): # 先天初始化過程中形成的屬性 self.brand = brand self.model = model def call(self): print('正在打電話。。') iphone = Mobile('apple', 'xr') # 獲取屬性 # print(iphone.brand) # 修改屬性 # iphone.brand = 'aple' # 定義新的例項屬性 # 後天養成的特性 # iphone.video = '美顏' # print(iphone.video) # 獲取一個不存在的屬性 # 如果獲取不存在的屬性,程式碼會報錯 # print(iphone.games) # AttributeError: 'Mobile' object has no attribute 'games' # 動態獲取屬性 # getattr 內建函式 # print(getattr(iphone, 'games')) # 還是報錯:AttributeError: 'Mobile' object has no attribute 'games' # default ,如果獲取不到屬性名,傳入 default 預設值,就不會報錯了 # getattr 不會修改原來的物件的屬性 print(getattr(iphone, 'games', '吃雞')) # print(iphone.games,) # 還是會報錯,因為iphone 沒有games屬性 # 動態修改屬性 setattr(iphone, 'games', '王者榮耀') print(iphone.games) # 王者榮耀