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國內源

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調試

  • 是暫停代碼的運行去獲取現在的數據狀態
    • print
    • 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+ 可讀,可寫

(二)、路徑

1、路徑

  • sys . path 包含項目開始根目錄路徑和 python 內置的目錄路徑

    • 模塊導入的搜索路徑: sys.path
      • 模塊導入不了時可以用來檢查
      • python去查找包或模塊,相當於python里的地圖
      • 返回的是一個列表
  • 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) # 王者榮耀
    
Tags: