python接口測試自動化之python基礎語法
一、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 //pypi.tuna.tsinghua.edu.cn/simple
python國內源:
清華://pypi.tuna.tsinghua.edu.cn/simple
阿里云://mirrors.aliyun.com/pypi/simple/
中國科技大學 //pypi.mirrors.ustc.edu.cn/simple/
華中理工大學://pypi.hustunique.com/
山東理工大學://pypi.sdutlinux.org/
豆瓣://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 = "//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) # 王者榮耀