Python语法--Mooc七月
生活随笔
收集整理的這篇文章主要介紹了
Python语法--Mooc七月
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
參考資料備用:
python ABC
3.8.2Documentation
python cookbook 3rd
pip安裝超時解決辦法
vscode小技巧
- 打開命令窗口:Ctrl+`
- 注釋:單行 – Ctrl+/,多行 – Shift+Alt+A
- cmd:cls清屏
- Ctrl + Shift + O:快速定位函數(shù)
目錄速查
Python入門導學
Python基本類型:數(shù)字,字符串
組:列表,元組,集合,字典
變量與運算符
分支、循環(huán)、條件和枚舉
包、模塊、類
函數(shù)
面向?qū)ο?#xff1a;類,實例,方法,繼承
正則表達式和JSON
枚舉類型,閉包
匿名函數(shù)、高階函數(shù)、裝飾器
爬蟲實戰(zhàn)
Python雜記
Python入門導學
返回
特點
- 簡潔;豐富的標準庫和第三方庫(電子郵件、GUI);面向?qū)ο?#43;函數(shù)式編程;易于上手,難于精通;既有動態(tài)腳本的特性,又有面向?qū)ο蟮奶匦浴?/li>
- 豆瓣、知乎
- Simple is better than complex.
Now is better than never. Although never is often better than an right now. - 缺點:慢
編譯型語言(C、C++)–運行效率
解釋型語言(Javascript,Python)–開發(fā)效率
一個經(jīng)典誤區(qū):編程 = web編程?
- 世界上不是只有網(wǎng)站,還有很多問題需要編程來解決。
- web是基礎–爬蟲、數(shù)據(jù)服務提供、數(shù)據(jù)分析。
- 互聯(lián)網(wǎng)時代,有網(wǎng)絡的地方就需要web。
- web編程確實是最好的語言實踐–業(yè)務邏輯思考能力、寬廣的知識面。
Python能做什么
- 爬蟲
- 大數(shù)據(jù)與數(shù)據(jù)分析(Spark)
- 自動化運維與自動化測試
- web開發(fā):Flask,Django
- 機器學習:Tensor Flow(谷歌)
- 膠水語言:能夠把其他語言制作的各種模塊(尤其是C/C++)輕松地聯(lián)結在一起
正確打開方式:遇到問題時,隨手拿起Python寫個工具
什么是寫代碼&Python的基本類型
返回
什么是代碼,什么是寫代碼
- 代碼: 現(xiàn)實世界事物在計算機世界中的映射
- 寫代碼: 將現(xiàn)實世界中的事物用計算機語言來描述
數(shù)字
整型與浮點型
- 整數(shù):int
其他語言有short,int,long - 浮點數(shù):float
其他語言有單雙精度之分,Python沒有
type(2/2)是float(1.0),type(2//2)是int(1)
*雙斜杠是“整除”
10、2、8、16進制&表示&轉(zhuǎn)換
- 其他進制:60s = 1min
- 2進制:0b10,直接在IDLE回車就會返回2
8進制:0o10 = 8
16進制:0x10 = 16 - bin():將其他進制轉(zhuǎn)換成2進制
oct():將其他進制轉(zhuǎn)換成8進制
hex():將其他進制轉(zhuǎn)換成16進制
int():將其他進制轉(zhuǎn)換成10進制
布爾類型和復數(shù)(屬于數(shù)字分類)
- bool:表示真、假
True/False,要大寫
只要非 0/空串/空列表/None,就都是True - complex:復數(shù)(36j)
抓大放小,抓住重點深入
字符串str
單雙引號
- 單引號和雙引號–成對出現(xiàn)
"let's go",'let\'s go'
多行字符串
- 一行79,回車字符\n會讀進字符串中
- IDLE寫'\n'輸出還是'\n',不換行
print("""hello world\nhello world\n""")會輸出換行 - 單引號換行:
輸出'helloworld'
轉(zhuǎn)義字符–特殊的字符
- 表示無法“看見”的字符
- 與本身語法有沖突的字符
- \n換行
\r回車:光標回到本行首位置,不會換行
\t橫向制表符:TAB
\'單引號
原始字符串
- 字符串前加r/R,原始字符串–所看即所得。
- 'let's go'無法通過加r解決–引號要成對出現(xiàn)
字符串運算
- +:拼接
*數(shù)字:重復數(shù)字倍 - 獲取單個字符:“字符串”[i],負數(shù)從后往前數(shù)
獲取一段字符:步長
'hello world'[0:4]輸出'hell',要讀到字符下一位
'hello world'[0:-1]輸出'hello worl' - 怎么輸出world?
"hello world"[6:],默認取字符串最后一位
"hello world"[-5:],后往前數(shù)第5位,到末尾
“組”的概念與定義
返回
列表list
定義
列表內(nèi)部可以存放不同類型元素
列表內(nèi)部可以嵌套列表
基本操作
- 取元素
- 合并列表:+
- *3:把列表內(nèi)元素重復三次
元組tuple
- 同列表
- type(('hello'))返回值str:為什么只有一個元素的元組是元素的類型?
答:()內(nèi)只有一個元素,python優(yōu)先認為()是數(shù)學運算符,返回數(shù)學運(比如(1))。
表示只有一個元素的元組:(1,)
表示一個元素都沒有的空元組:()
type([1])返回值是list
序列總結
- 序號
- 切片
"hello world"[0:8:2]返回'hlow–在0-7的切片內(nèi)隔1取元素? - +,*
- 元素是否在序列中:in,not in,返回bool值
3 in [1,2,3,4,5]返回True - len(),max(),min():返回序列長度、最大值、最小值
max、min不支持不同類型元素比較 - ord()返回單個字符的ASC碼(字符串不行)
集合set
- 最大的特點——無序
{1,2,3,4,5}不支持序號、切片 - 不重復
{1,1,1,2,2,3,4,5}返回{1,2,3,4,5} - len()
in、not in - {1,2,3,4,5,6} - {3,4}:兩個集合取差集
{1,2,3,4,5,6} & {3,4}:兩個集合取交集
{1,2,3,4,5,6} | {3,4,7}:兩個集合取并集 - 怎么定義空的集合?
type({})返回dict類型 – 不可用
type(set())返回set類型 – 正確操作
字典dict
- 很多的key和value,set的延生而不是序列的
{key1:value, key2:value, ……} - 最常用操作:通過key得到/訪問value
- key值不可重復
- value類型無限制,可以也是一個字典
key必須是不可變的類型 – 字符串和元組不可變,列表可變
變量與運算符
返回
變量
什么是變量
- 名字:起名字要有意義 – 命名可讀性要強,多查單詞
- =:賦值符號
命名規(guī)則
- 字母、數(shù)字、下劃線
- 首位不能是數(shù)字
- 系統(tǒng)關鍵字(保留關鍵字)不能用在變量名中
非保留的也盡量不要用,血和淚的教訓。
值類型與引用類型
a = 1 b = a a = 3 #a指向了新的int(3) print(b) #1a = [1,2,3,4,5] b = a a[0] = '1' #a沒有指向新的list,而是改變原來的list print(b) #['1',2,3,4,5]- 值類型:不可改變
int、str、tuple
引用類型:可改變
list、set、dict
- list和tuple:
元組不可修改,能用元組就用元組 – 代碼穩(wěn)定性考慮
運算符
算術運算符
+,-,*,/,//整除,%,**指數(shù)(2**5 = 32)
賦值運算符
- 先做運算再賦值
- python中沒有自增自減運算
比較運算符
- 返回一個bool值
邏輯運算符
- 與、或、非
- int,float中0被認為是False
字符串中空字符串""是False
列表中空的列表[]被認為是False - and 和 or 的返回值 – 最后一個讀到的內(nèi)容
1 and 2返回2,2 and 1返回1 – 讀到第二個數(shù)字才能判斷
1 or 2返回1 – 讀到第一個1的時候就能判斷了
成員運算符
- in,not in
- 字典類型判斷的是key
身份運算符
- is,is not– 兩個變量的身份是否相等
- id()查看他們的地址,地址相同身份相同 – is比較的是地址
判斷變量的值、身份、類型 – 對象3特征
- ==值
is身份
isinstance(a, int)類型 - isinstance(a, (int, str, float)) a是否是元組里三個類型中的一個,是返回True,否返回False
位運算符
b = 3 bin(b) #'0b11',3 bin(~b) #'-0b100',前面取負末位+1,-4 a = 2 bin(a) #'0b10' bin(a<<1) #'0b100' bin(a>>3) #'0b0'分支、循環(huán)、條件和枚舉
返回
表達式
什么是表達式
表達式是運算符和操作數(shù)組成的序列
表達式優(yōu)先級
- 一般右結合,出現(xiàn)=左結合,與運算符優(yōu)先級無關
- 運算符優(yōu)先級最高,然后是比較,邏輯運算符最低:not > and > or
- 加輔助括號可以改變運算順序
流程控制語句
條件控制
if d:a = input() #讀入的是字符串pass #空語句,占位語句 elif:pass else:passpylint規(guī)范
- python中實際沒有常量,用大寫
- 每個模塊開頭一段注釋,說明
- tab 四個空格、切換到下一個代碼編輯區(qū)域
- python沒有switch
elif代替,或者字典處理 - a,b不同時為False:a or b
循環(huán)
while的循環(huán)場景
- 遞歸
for
for target_list in expression_list:pass else:pass #列表全部打完以后執(zhí)行else,強制break結束時不會執(zhí)行else- range
python的組織結構-包、模塊、類
返回
- 包(文件夾,包含__init__.py),模塊,類(用類把函數(shù)、變量組織起來)
包.模塊seven.c4,子包 - __init__.py的模塊名就是包的名字
導入
import c7 #同級,導入模塊 print(c7.a)import t.c7 #子包中 print(t.c7.a)from t.c7 import a, def #導入變量、函數(shù) print(a)from t import c7 #導入模塊 print(c7.a)from t.c7 import * #導入所有變量和函數(shù),能不用就不用 __all__ = ['a', 'c'] #在模塊開頭,改變*關于全部的定義 #模塊的內(nèi)置屬性#末尾加反斜杠可以換行, ()也可以換行 from c7 import a, b\ c from c7 import (a, b c)init.py
- 導入包時自動運行:
無論是導入包還是導入包下面的模塊,都會自動運行__init__.py - 在__init__.py內(nèi)設置__all__可以控制*時導入的包內(nèi)模塊
- 批量導入包
- 注意點:
① 包和模塊不會被重復導入
② 避免循環(huán)導入
③ python導入模塊時會執(zhí)行所導入模塊的代碼
模塊內(nèi)置變量
- dir()返回當前模塊的變量列表
dir(sys)返回指定模塊sys的變量列表 - 錯誤信息:堆棧信息(路徑)+詳細信息(原因)
- __doc__存放模塊注釋信息
__file__存放文件路徑
入口文件和普通模塊內(nèi)置變量的區(qū)別
print('package: ' + (__package__ or 當前模塊不屬于任何包)) #當前模塊不屬于任何包 print('name: ' + __name__) #__main__ print('doc: ' + (__package__ or 當前模塊沒有文檔注釋)) print('file: ' + __file__) #文件名c9.py__name__的經(jīng)典應用
if __name == '__main__':pass #作為可執(zhí)行文件時才會執(zhí)行 #Make a script both importable and executabl- python -m seven.c15把c15按模塊執(zhí)行,命名空間(?)
python seven\c15.py路徑方式
相對導入和絕對導入
- 決定頂級包的是可執(zhí)行文件
package2.package4,demo不是頂級包 - 絕對導入必須從頂級包開始
- 相對路徑:
.表示當前目錄
…表示上層目錄
…表示上上層目錄 - 入口文件不能使用相對路徑
因為入口文件的__name__被設置成__main__無法作為路徑使用
一定要在路口文件使用相對路徑:
回到demo的上一級,python -m demo.main,此時相對導入可用,輸出demo.package2.package4 - 相對導入
Python 函數(shù)
返回
函數(shù)
- round(a, 2)保留小數(shù)點后兩位,同時四舍五入
- help(round)查看內(nèi)置函數(shù)
- import this打印python之禪
- 特點:功能性、隱藏細節(jié)、避免編寫重復的代碼
函數(shù)的定義和運行特點
def funcname(parameter_list):pass #1. 參數(shù)列表可以沒有 #2. return value None- [Previous line repeated 995 more times]遞歸超過995次
返回多個結果
def damage(skill1, skill2):damage1 = skill1 * 3damage2 = skill2 * 2return damage1, damage2skill1_damage, skill2_damage = damage(3, 4) #用兩個變量(有意義的變量名)存放兩個返回值 #序列解包序列解包
d = 1, 2, 3 print(type(d)) #tuplea, b, c = d #序列解包 a, b = [1, 2, 3] #報錯,用兩個變量接收三個值a=b=c=1 #連續(xù)賦值√參數(shù)
必須參數(shù)與關鍵字參數(shù)
- 必須參數(shù):
c = add(3, 2) - 關鍵字參數(shù):
c = add(y=3, x=2),不用固定實參的輸入順序 - 備注:
① 二者的差別在函數(shù)的調(diào)用上,不在定義上
② 定義了多少形參就要傳入多少實參
默認參數(shù)
- 定義的時候給形參默認值
- 調(diào)用時正常傳遞實參即可按順序覆蓋,沒有默認值的形參必須傳入實參
- 必須傳入的參數(shù)必須放在默認參數(shù)前面
- print_student('lxxx', age=17)可以不按參數(shù)列表順序傳入改變默認值
- 默認值參數(shù)和必須參數(shù)不能混著調(diào)用
print_student('lxxx', gender='nv', 17, college='xx')
可變參數(shù)/形參列表可變
def demo(*param):print(param) print(type(param)) #tupledemo(1,2,3,4,5,6)a = (1,2,3,4,5) demo(a) #報錯,傳遞進入的是一個元組 demo(*a) #√ 類似解包,傳入的是可變參數(shù)def demo(param1, param2=2, *param):print(param1) print(param2)print(param)demo('a', 1,2,3) #a #1 默認值參數(shù)在前,讀完才讀可變參數(shù) #(2,3)def demo(param1, *param, param2=2):print(param1) print(param2)print(param)demo('a', 1,2,3, 'param') #a #(1,2,3,'param') 可變參數(shù)會把剩余全部傳入可變 #2demo('a', 1,2,3, param2='param') #a #(1,2,3) #param盡量保證形參列表的簡單
關鍵字可變參數(shù)/任意個數(shù)的關鍵字參數(shù)
def city_temp(**param)print(type(param)) #dictfor key,value in param.items():print(key, ':', value)print(param)a = {'bj':'32c', 'sh':'31c'} city_temp(**a) city_temp() #{}作用域
變量作用域
c = 50 #全局變量 def demo():c = 10 #局部變量print(c) #10def demo1():print(c) #50demo() print(c) #50def demo2():for i in range(0,9):a += iptint(a) #python沒有塊級變量的概念作用域鏈
c = 1 def func1():c = 2def func2():c = 3print(c)func1() #3 2 1global關鍵字
def demo():global cc = 2demo() print(c)- 全局變量在整個程序里面都能用
小作業(yè)1-合成石頭劃算不
要求
代碼
- stone.py
- main.py
結果
面向?qū)ο?/h2>
返回
類
- 有意義的面向?qū)ο蟮拇a
定義
- 首字母大寫,不要用下劃線連接
- 類只負責描述定義,不負責執(zhí)行=類內(nèi)不能運行調(diào)用這個類
一個模塊專門用來定義類,調(diào)用寫進另外的模塊 - 類最基本的作用:封裝
- 方法與函數(shù)的區(qū)別
方法:設計層面
函數(shù):程序運行的過程式
類和對象的關系
- 實例化
- 類的設計:行為與特征
- 類是模板,可以產(chǎn)生很多不同的對象
構造函數(shù)
- 實例化的過程中會自動調(diào)用構造函數(shù),一般不顯示調(diào)用構造函數(shù)
- 構造函數(shù)不能返回除了None以外的值(也不是用來返回什么東西的)
- 構造函數(shù)的作用,讓模板生成不同的對象
類變量、實例變量、self
class Student():name = 'qiyue' #類變量age = 0def __init__(self, name, age): #添加參數(shù)以后必須要傳入?yún)?shù)self.name = name self.age = ageprint('student') #實例變量student1 = Student('石敢當', 18) student2 = Student() #報錯 print(student1.name) #石敢當 print(Sturent.name) #qiyue- 為什么要寫self,顯勝于隱
實例方法、類方法、靜態(tài)方法
- 實例方法:def do_homework(self):
實例可以調(diào)用的方法,操作實例變量 - 在實例方法里面訪問類變量
不能直接用變量名訪問類變量
''' 實例方法調(diào)用類變量 ''' class Student():name = ''age = 0sum_s = 0def __init__(self, name, age)self.name = nameself.age = age#self.__class__.sum_s += 1#print('當前學生總數(shù)為:' + str(self.__class__.sum_s))''' 定義類方法 '''@classmethoddef plus_sum(cls)cls.sum_s += 1print(cls.sum_s)''' 定義靜態(tài)方法 '''@staticmethoddef add(x,y):print('This is a static method')s1 = Student('石敢當', 18) #當前學生總數(shù)為:1 Student.plus_sum() s2 = Student('喜小樂', 16) #當前學生總數(shù)為:2 Student.plus_sum() s1.plus_sum() #python中實例對象可以調(diào)用類方法,但是不建議這么干! s1.add(1,2) Student.add(1,2)- 靜態(tài)方法和面向?qū)ο箨P系很弱,像一個普通函數(shù),一般不推薦使用
成員可見性
- 成員:變量和方法
- 類有內(nèi)外之分
- 提倡的規(guī)范:
所有類下變量的更改都通過方法操作(對數(shù)據(jù)保護,避免不規(guī)范操作)
公開和私有
- 公開的 public:可以在外部直接調(diào)用
私有的 private:外部無法直接讀取/設置 - python怎么判斷公開還是私有?
方法在開頭加雙下劃線__,變?yōu)樗接?br /> 為什么__init__可以在外部調(diào)用?因為它后面也有下劃線!這是python內(nèi)置函數(shù)的命名風格
沒有什么是不可以訪問的!
s1 = Student('石敢當', 18) s2 = Student('喜小樂', 16) s1.__score = -1 #給實例對象創(chuàng)建了一個新的屬性并賦值,不是給私有成員賦值 print(s1.__score) #-1 print(s2.__score) #報錯 print(s1.__dict__) #打印變量 #{'name':'石敢當', 'age':18, '_Student__score':59, '__score':-1} print(s1._Student__score) #成功讀取!但是沒什么意義不建議這么玩面向?qū)ο笕筇匦?/h3>
- 繼承性、封裝性(抽象程度高)、多態(tài)性
繼承性
- 避免定義重復的方法、重復的變量
from c6 import Human
'''
class Human():sum = 0def __init__(self, name, age):self.name = nameself.age = agedef get_name(self):print(self.name)
'''
class Student(Human):passprint(Student.sum) #0,從Human里面繼承的
s1 = Student('石敢當', 18)
print(s1.name) #以下都可以繼承
print(s1.age)
s1.getname()
- 單繼承。Python允許多繼承,單繼承都沒用好請別用多繼承
- 子類與父類方法同名
正則表達式與JSON
返回
- 正則表達式是一個特殊的字符序列,檢測一個字符串是否與我們所設定的字符序列相匹配,實現(xiàn)快速檢索文本、替換文本的操作。
① 檢查一串數(shù)字是否是電話號碼
② 檢測一個字符串是否符合E-mail
③ 把文本里指定的單詞替換為另一個單詞
元字符
元字符與普通字符
import re #找a中的所有數(shù)字 a = 'C0C++7Java8C#9Python6Javascript' r = re.findall('\d', a) #\d匹配一個數(shù)字符,元字符 #\D匹配所有非數(shù)字符 print(r) #['0','7','8','9','6']正則表達式匹配的是字符
菜鳥教程–元字符列表
字符集
import re #找s中找出中間字符是c或者f的單詞 s = 'abc,acc,adc,aec,afc,ahc' r = re.findall('a[cf]c', s) #普通字符+字符集 print(r) #[acc','afc'] r = re.findall('a[^cfd]c', s) #取反操作 print(r) #['abc','aec','ahc'] r = re.findall('a[c-f]c', s) #取范圍 print(r) #['acc','adc','aec','afc']- 普通字符用于輔助定界
- 出現(xiàn)在字符集里面的字符之間是或關系
概括字符集
- \d = [0-9],\D = [^0-9]
- \w = [A-Za-z0-9_]匹配數(shù)字、字母、下劃線,\W
['p','y','t','h','o','n'],[' ','&','\n','\r','\t'] - \s
[' ','\n','\r','\t']–空白字符 - .匹配除了換行符以外的所有符號
數(shù)量詞
a = 'python 1111java678ph' r = re.findall('[a-z]', a) print(r) #單個字母的序列 r = re.findall('[a-z][a-z][a-z]', a) #連續(xù)匹配3位字符 print(r) #['pyt','hon','jav','php'] r = re.findall('[a-z]{3}', a) print(r) #['pyt','hon','jav','php'] r = re.findall('[a-z]{3,6}', a) #字符位數(shù)范圍3-6 print(r) #['python','java','php']貪婪和非貪婪
- python默認貪婪的匹配方式,一直匹配到某個字符不滿足他的要求
匹配0次1次或者無限次
- *匹配*前面的字符0次或者無限多次
- +匹配*前面的字符1次或者無限多次
- ?匹配*前面的字符0次或者1次
- ?可以用來去重
邊界匹配
- ^從字符串的開頭開始匹配
- $從字符串的末尾開始匹配
組
import re s = 'pythonpythonpythonpythonpythonpython' r = re.findall('pythonpythonpython', s) print(r) #['pythonpythonpython', 'pythonpythonpython'] r = re.findall('python{3}', s) print(r) #[],只能匹配單個字符出現(xiàn)的次數(shù) r = re.findall('(python){3}', s) print(r) #['python', 'python'] ???? r = re.findall('(python){3}[JS]', s) print(r) #[]匹配模式參數(shù)
- re.I表示匹配忽視字母大小寫
- re.S表示.匹配所有符號,包括\n
re模塊下的其他函數(shù)
re.sub正則替換
import re lanuage = 'PythonC#Java' lanuage1 = 'PythonC#JavaC#PHPC#' r = re.findall('C#', 'GO', lanuage) print(r) #PythonGOJava r = re.findall('C#', 'GO', lanuage1, 0) #所有符號的都會被替換 print(r) #PythonGOJavaGOPHPGO r = re.findall('C#', 'GO', lanuage1, 1) #符合條件的字符替換的最大次數(shù)1 print(r) #PythonGOJavaC#PHPC#lanuage1 = lanuage1.replace('C#', 'GO') #內(nèi)置函數(shù)實現(xiàn)替換 print(lanuage1) #PythonGOJavaGOPHPGO- sub()的第二個參數(shù)可以是函數(shù)
- 把函數(shù)作為參數(shù)傳入的作用
search和match
- match()從首字母開始匹配,首字母沒有就返回空
- search()搜索字符串,一旦找到第一個就會返回
- 兩者匹配成功立刻停止搜索,findall()會匹配所有符合的結果
group分組
#匹配life和python中間的內(nèi)容 s = 'life is short,i use python' r = re.search('(life.*python)', s) print(r.group(0)) #life is short,i use python只有一個組 r = re.search('life(.*)python', s) print(r.group(0)) #life is short,i use python,第一組存放整體 print(r.group(1)) # is short,i use r = re.findall('life(.*)python', s) print(r) #[' is short,i use ']s = 'life is short, i use python, i love python' r = re.findall('life(.*)python(.*)python', s) print(r.group(0)) #life is short, i use python, i love python print(r.group(1)) # is short,i use print(r.group(2)) #, i love print(r.group(0,1,2)) #('life is short, i use python, i love python', ' is short,i use ', ', i love ') 用元組返回 print(r.groups()) #(' is short, i use ', ', i love ') 不會返回完整的,只會返回匹配的部分正則表達式的學習建議
- 完成內(nèi)置函數(shù)無法完成的字符串相關問題
- 常用的qq號,電話號碼,email的匹配,可以直接用別人寫好的提高效率,分析一下別人怎么寫的(學習角度)
- 避免過度依賴內(nèi)置函數(shù),有意識的多用正則表達式
JSON
- JavaScript Object Notation–JavaScript對象標記
- 是一種輕量級的數(shù)據(jù)交換格式
- 字符串是JSON的表示形式
- 符合JSON格式的字符串叫JSON字符串{"name":"qiyue"}
- 優(yōu)勢:易于閱讀、解析,網(wǎng)絡傳輸效率高,適合用于跨語言交換數(shù)據(jù)
反序列化
- 由字符串到某種語言上的數(shù)據(jù)結構–反序列化
序列化
- python數(shù)據(jù)類型向JSON字符串轉(zhuǎn)換的過程
| object | dict |
| array | list |
| string | str |
| number | int |
| number | float |
| true | True |
| false | False |
| null | None |
- 調(diào)用服務拿到字符串(JSON)進python處理
JSON/JSON對象/JSON字符串
- JSON:是一種輕量級的數(shù)據(jù)交換格式
- JSON字符串:符合JSON格式的字符串叫JSON字符串
- JSON對象:JavaScript里的說法
- JSON數(shù)據(jù)類型:中間數(shù)據(jù)類型/語言格式
- JSON是REST服務的標準格式
Python高級語法與用法
返回
枚舉
枚舉是個類啊!
form enum import Enumclass VIP(Enum):#常量大寫,Python沒有常量概念#枚舉下的類型不易更改、不能重復--枚舉類型的保護功能YELLOW = 1GREEN = 2BLACK = 3RED = 4print(VIP.YELLOW) #VIP.YELLOW,并不是1- 枚舉的意義所在,關注的是名字而不是數(shù)字,重在標簽
相比普通類有什么優(yōu)勢
yellow = 1 green = 2{'yellow':1, 'green':2}class TypeDiamond():yellow = 1green = 2- 缺陷:可變;沒有防止相同值的功能
相關操作
- 取值
- 遍歷
- 比較
枚舉轉(zhuǎn)換
- 在數(shù)據(jù)庫里存儲–用數(shù)字代表類型
- 編寫代碼時顯示定義一個枚舉類,用枚舉類下的每一個枚舉類型對應數(shù)據(jù)庫中的每個數(shù)值
- 如何把數(shù)字和枚舉類型對應起來?
注意事項
- 標簽名不能相同,數(shù)值可以相同,但是!!
允許有兩個類型數(shù)值相等,此時第二種可以看成是第一種的別名 - 遍歷時不會打印別名
- IntEnum
- 枚舉類型在python里面是單例模式,實例化沒有意義
進階–函數(shù)式編程
- 基礎知識用來寫出代碼,高階知識用來寫出可復用的代碼(包、類庫)
嘗試著寫包和類庫,體會高級語法的好處,實踐出真知啊!
閉包
- Python一切皆對象
- 函數(shù)既可以作傳入?yún)?shù),又可以作返回結果
- 閉包:函數(shù)及其在定義時外部的環(huán)境變量(非全局),不會受重新復賦值的影響
- 經(jīng)典誤區(qū)
- 小作業(yè):計算旅行者的路徑長度
- 閉包特點:在模塊層面簡介調(diào)用函數(shù)內(nèi)部的局部變量
函數(shù)式編程
返回
匿名函數(shù)
lambda表達式
- 定義時不需要定義它的函數(shù)名
三元表達式
- xy,x大于y則返回x,否則y
map(class)
list_x = [0,1,2,3,4,5,6,7,8,9]def square(x):return x*xfor x in list_x:square(x)r = map(square, list_x) print(r) #<map object at 0x023D4A30> print(type(r)) #<class 'map'> print(list(r)) #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81],轉(zhuǎn)化成列表- map(函數(shù), 元素集合):將元素按函數(shù)方法映射成新的元素集合
map 與 lambda
- 列表傳入個數(shù)與lambda的參數(shù)列表個數(shù)相同
- 結果列表元素個數(shù)取決于傳入列表中元素少的那個
高階函數(shù)
reduce
from functools import reduce#連續(xù)計算,連續(xù)調(diào)用lambda list_x = [0,1,2,3,4,5,6,7,8,9] r = reduce(lambda x,y: x+y, list_x) #取前兩個元素,每次lambda運算的結果作為x送入后面的運算 print(r) #45list_x = ['0','1','2','3','4','5','6','7','8','9'] r = reduce(lambda x,y: x+y, list_x, 'aaa') #初始值作為第一次運算的傳入?yún)?shù) print(r) #aaa0123456789filter–過濾
- 幫助我們過濾掉不符合定義格式的元素
- 函數(shù)返回至為False
函數(shù)式編程vs命令式編程
- 命令式編程:def、if else、for
- 函數(shù)式編程:map、reduce、filter、lambda
- lisp居然是函數(shù)式編程的鼻祖!
裝飾器
- 類此C#的特性,JAVA的注解
對修改是封閉的,對擴展是開放的
- 非裝飾器方法
- 裝飾器方法–裝飾器是一種模式
python語法糖–甜、甜的?
- 語法糖: 真正體現(xiàn)裝飾器功能的高光時刻!即沒有改變函數(shù)內(nèi)部實現(xiàn),也沒有改變函數(shù)的調(diào)用
- 可以接受定義時候的復雜,但是絕對不能接受調(diào)用時候的復雜!
- 如果函數(shù)帶各種各樣的參數(shù)呢?
如何兼容通用關鍵字參數(shù)?
import timedef decorator(func): #裝飾def wrapper(*args, **kw): #封裝print(time.time())func(*args, **kw) #不管函數(shù)是怎么定義的,都可以用這個抽象的函數(shù)調(diào)用方式return wrapper@decorator def f1(func_name):print('This is a function named ' + func_name)@decorator def f2(func_name1, func_name2):print('This is a function named ' + func_name1)print('This is a function named ' + func_name2)@decorator def f3(func_name1, func_name2, **kw): #關鍵字參數(shù)print('This is a function named ' + func_name1)print('This is a function named ' + func_name2)print(kw)f1('lizzy') f2('lxxx1', 'lxxx2') f3('test1', 'test2', a=1, b=2, c='123')''' 1587521895.7875009 This is a function named lizzy 1587521895.7885008 This is a function named lxxx1 This is a function named lxxx2 1587521895.7915008 This is a function named test1 This is a function named test2 {'a': 1, 'b': 2, 'c': '123'} '''- func(*args, **kw) 不管函數(shù)是怎么定義的,都可以用這個抽象的函數(shù)調(diào)用方式
裝飾器小結
- 裝飾器優(yōu)勢
① 代碼的穩(wěn)定性角度:對被封裝的單元做出修改–通過裝飾器改變函數(shù)的行為
② 代碼的復用性角度:語法糖
實戰(zhàn):原生爬蟲
返回
- 爬蟲的目的性要明確
整理爬蟲的常規(guī)思路
- 鼠標右鍵–檢查:開html信息
- 點擊信息框左上角的小箭頭
點擊頁面中需要的信息–自動定位到html信息中所屬的代碼段 - 數(shù)據(jù)提取層級分析:精準選取定位標簽,選閉合的父級別標簽,盡量不要選兄弟標簽
- 正則分析
- 數(shù)據(jù)精煉
- 數(shù)據(jù)處理(分析完成你的需求)
錯誤
- UnicodeDecodeError ‘utf-8’ codec can’t decode byte 0x8b in position 1: invalid start byte報錯分析
- StringIO和BytesIO–廖雪峰
- gizp模塊介紹–python文檔
① 報錯代碼
② 調(diào)試代碼
from urllib import request from io import BytesIO #BytesIO實現(xiàn)在內(nèi)存中讀寫bytes import gzip #壓縮與解壓縮的模塊class Spider():url = 'https://www.douyu.com/g_jdqs'def __fetch_content(self):r = request.urlopen(Spider.url)htmls = r.read()#print(type(htmls)) <class 'bytes'>buff = BytesIO(htmls) #寫入的不是str,而是經(jīng)過UTF-8編碼的bytes,即用一個bytes初始化BytesIO#print(type(buff)) <class '_io.BytesIO'>f = gzip.GzipFile(fileobj=buff) #將BytesIO對象解壓縮成GzipFile對象fprint(type(f)) #<class 'gzip.GzipFile'>htmls = f.read().decode('utf-8') #讀取f中的字節(jié)數(shù)據(jù)并按utf-8解碼為strprint(type(htmls)) #<class 'str'>a = 1def go(self):self.__fetch_content()s = Spider() s.go()③ 修改代碼
from urllib import request from io import BytesIO import gzipclass Spider():url = 'https://www.douyu.com/g_jdqs'def __fetch_content(self):r = request.urlopen(Spider.url)htmls = r.read()buff = BytesIO(htmls)f = gzip.GzipFile(fileobj=buff)htmls = f.read().decode('utf-8')a = 1def go(self):self.__fetch_content()s = Spider() s.go()- 我跳票了我去爬B站學習直播區(qū)了再見斗魚!
- anomalous backslash in string: ‘\s’. string constant might be missing an r prefix.
問題:\s首先被認為是轉(zhuǎn)義字符,在正則中多加一個\
解決:([\\s\\S]*?)加一個反斜杠 - root_info提取不到信息:頁面顯示的數(shù)據(jù)格式和抓取的數(shù)據(jù)格式有出入,根據(jù)抓取到的數(shù)據(jù)修改正則表達式
代碼規(guī)范
- 模塊、類、方法:塊注釋,內(nèi)部首部多行
- 語句注釋:在上面,注釋上空行
- 不要濫用空行,不要在一個函數(shù)里面寫多行代碼(函數(shù)越小越靈活復用性越高,10-20行,最多30行)
- 寫出來也要寫好
- 爬蟲擴展:BeautifulSoup、Scrapy等框架;爬蟲、反爬蟲、反反爬蟲;ip如果被封了–代理ip庫
實現(xiàn)代碼
- main.py
- spider.py
存在的問題與改進方向
- 動態(tài)加載的頁面只能讀取30條信息–如何讀取動態(tài)頁面?
- 如何使程序間隔xx時間重復爬取更新信息
- 圖形界面數(shù)據(jù)展示
- 獲得的數(shù)據(jù)還能做哪些方向的分析……?
Pythonic與Python雜記
返回
用字典代替switch
switcher = {0 : 'Sunday',1 : 'Monday',2 : 'Tuesday' }day = 2 day_name = switcher[day] print(day_name)day = 6 day_name = switcher[day] print(day_name) #報錯,6不存在 #get()方法有容錯性 day_name = switcher.get(day, 'Unknown') #找不到時返回Unknown print(day_name)- 字典內(nèi)部對應為函數(shù)(實現(xiàn)一個分支多個語句)
列表推導式
a = [1,2,3,4,5,6,7,8]#map實現(xiàn) b = map(lambda i: i*i, a) print(list(b))#列表推導式實現(xiàn) b = [i*i for i in a] print(b) #[1, 4, 9, 16, 25, 36, 49, 64] b = [i**3 for i in a] print(b) #[1, 8, 27, 64, 125, 216, 343, 512]- 推薦:有選擇性的篩選運算的場合
- 列表、字典、元組、集合都可以用
- 字典如何編寫列表推導式
iterator與generator
- 可迭代對象(凡是可以被for in遍歷的),迭代器
- 可迭代對象不一定是迭代器(列表元組字典),迭代器一定是可迭代對象
- 如何讓自定義的class可以被遍歷?–迭代器。
- 如何迭代兩次?
- 生成器–yield的用法
None
- 無論是從【類型】還是【值】上面來講,【None】都不等于【空字符串、空列表,0,False】
- not a和a is None等同嗎?
- 推薦的判空操作:
if a:
if not a:
不要用None來進行判空操作
對象存在不一定是True
- None永遠對應False
- 自定義的對象和True和False是怎么對應的?
- __len__與__bool__內(nèi)置方法
我!結!課!了!
總結
以上是生活随笔為你收集整理的Python语法--Mooc七月的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据校验之Checksum算法
- 下一篇: 纵横杯2020 web wp