python bif_小猪的Python学习之旅 —— 1.基础知识储备
引言:(文章比較長,建議看目錄按需學習~)
以前剛學編程的時候就對Python略有耳聞,不過學校只有C,C++,Java,C#。
和PHP有句"PHP是最好的語言" 這種家喻戶曉的騷話一樣,Python也有
"人生苦短,我用Python"。而接觸Python這個詞最多的場合就是在一些技術群里,
有些大佬張嘴動不動就說什么Py交易,作為潛伏在群里的開發萌新的我每次都
會忍不住會發出這樣的感慨:
而真正接觸了下Python是在上家公司,當時老大讓我寫個腳本去下載
倉庫里最近打包的apk,當時東湊湊西湊湊最后總算拼成了一個可運行
的py文件,因為不了解Python里的數據結構,全部用的字符串變量,
后面被老大教育了一番才知道有元組這種東西。因為本身做Android的,
Python用到的場合不多,加之覺得Kotlin有點意思,就沒去研究Python了。
前段時間,手頭的事做得差不多了,無聊四處張望時,看到隔壁后臺
小哥迅雷瘋狂下載東西,建文件夾,粘貼復制,不知道還以為他在給
小電影分類呢,后來一問才知道,運營讓他把服務器上所有的音頻
文件下下來,然后根據對應的類別下到對應文件夾,所以他做的事情
就是:迅雷批量下載過歌曲 -> 看mysql歌曲的分組 -> 建文件夾
-> 粘貼復制歌曲到這個文件夾下,咋一看,流程挺簡單的,然而有
4700多首歌,幾百個目錄,這樣慢慢搞怕是要搞幾天,而且常時間
機械化的重復某項工作,很容易出錯。看著一臉絕望的后臺小哥:
于心不忍,決定寫個py腳本來拯救他,腦子里也有了程序的大概邏輯:
1.讓后臺導出一份mysql建表語句,安裝mysql把表建起來;
2.Python連mysql,讀取表里的數據
3.編寫帶limit去重的sql查詢語句,查詢得到所有分類
4.得到的所有分類就是要創建的文件夾,迭代批量創建文件夾;
5.sql查詢歌曲下載url與分類,拼接,寫入到文件中;
6.讀取文件,迭代:下載url截取文件名與分類路徑拼接成文件
的完整路徑,調用下載相關函數下載url到對應路徑即可。
邏輯挺簡單明了的,然而各種坑,最后折騰了一天才能弄出來
遇到了下面這些問題:
1.最坑的解碼問題:默認使用Python2,中文亂碼,各種網上搜,
設置編碼方式,都沒用,頭皮發麻,特別是在截取文件名的時候。
后面換了一波Python3,很舒服,什么問題都沒了。
2.沒有對異常進行捕獲,有些資源失效404,下到中途才發現.;
3.想弄多線程下載的,因為Python很多基礎不知道,后面放棄了;
當看到所有文件都下載到了對應的位置,一種油然而生的成就感,
比起寫APP天天畫界面,請求,解析數據,顯示數據,有意思太多,
畢竟學習開發興趣很重要,索性從零開始學習下Python吧,越學越覺得:
理由上班時的閑暇時間,歷時兩周總算是把基礎知識的東西過了
一遍,遂有此文,畢竟初學者,有些地方可能理解有誤,望看到
的大佬不吝賜教,文中大部分內容摘自:
《Python 3 教程》與《小甲魚的零基礎入門學習Python》
有興趣的可以閱讀下這兩本書~
本文不是入門教程啊,完全沒有編程經驗的不建議閱讀!
完全小白可以看下這本:《編程小白的第一本Python入門書》
目錄
[TOC]
1.學習資源相關
API文檔
書籍
2.學習Python2還是Python3的問題
!!!Python 3的語法 不完全兼容 Python 2的語法!!!
菜逼剛學Python沒多久,不敢大聲嗶嗶,最直接原因:
Python 3默認使用utf-8,在處理中文的時候可以
減少很多編解碼的問題,而Python 2默認使用ascii。
另外的原因:與時俱進,IT行業發展那么迅速,完全過渡只是時間問題;
舉個例子:Android Studio剛出的沒多久的時候,各種說卡啊,垃圾,
只能開一個項目等各種嫌棄,不如Eclipse好用;然而現在開發Android
還是用Eclipse的都是會被歧視一波的,另外官方已經確定Python 2.7會
在2020年退休。So:人生苦短,我用Python3。
而且Python 2.7預計會在2020年退休
更多比較的文章可見:
3.開發環境搭建
Python下載安裝
Windows
傻瓜式下一步就好,記得勾選Add Python x.x to Path!勾選
了你裝完就不用自己去配置環境變量,安裝完畢后打開CMD輸入:
python3 -V 能查看到安裝的Python版本說明安裝成功,
如果提示錯誤:python3不是內部或外部命令之類的話,恭喜你
可以百度下:Python3環境變量配置 了~
Mac
方法一:官網下安裝包,傻瓜下一步;
方法二:如果有裝Homebrew,終端輸入:brew install Python3 安裝即可。
Ubuntu:一般內置,執行下述命令可查看版本,如果想安裝自己喜歡
的版本可以鍵入:sudo apt-get install python版本號 進行安裝
PyCharm下載安裝
其實在安裝完Python后就可以進行Python編程了,直接命令行輸入python3,
就可以使用自帶的IDLE進行開發了;又或者直接用Sublime Text或NotePad++
這類代碼查看工具直接編寫代碼,然后保存成后綴為.py的文件,然后python3
執行這個py文件就可以了。
雖然可以,但是挺不方便的,比如縮進問題,Python通過縮進來表示代碼塊,
代碼一多,某一行沒有正確的使用縮進,結果可能與你預期的相差甚遠。
智能提示,方便的依賴庫管理等,這兩個就不用說了吧,具體的還得你自己體會。
官網下載:https://www.jetbrains.com/pycharm/download/
下載Professional版本,傻瓜式安裝,打開后會彈出注冊頁面,
勾選License server,在License server address輸入注冊服務器,
網上搜很多,然后就可以愉快的進行py開發了。
軟件的基本使用也非常簡單,Jetbrains的IDE都是差不多的~
有一點要注意的地方是,如果你想切換項目依賴的Python版本號的話:
打開設置(Preference或settings),修改即可:
4.基本常識
1) 導包
有時項目中需要引入其他模塊或者模塊中的某個函數,需要用到import和
from...import,用法示例如下:
import sys # 導入整個模塊
from sys import argv # 導入模塊中的需要用到的部分
from urllib.error import URLError, HTTPError # 多個的時候可以用逗號隔開
from sys import * # 導出模塊中的所有
# 另外還可以使用as關鍵字為模塊設置別名,比如 import sys as s
# 調用的時候直接s.argv 這樣就可以了。
2) 關鍵字與標識符命名規則
在對變量或者方法名這些標識符進行命名的時候,需要注意,不能夠
與Python中的關鍵字相同,通過keyword.kwlist可以查詢所有的關鍵字:
需要import keyword模塊哦~
除了不能與與關鍵字相同外,標識符的命名規則:
由字母,數字和下劃線組成,且首字符必須為字母或下劃線,
Python對大小寫敏感;關于命名規范的問題,沒有什么
強制規定,整個項目保持統一就好,附上網上找的一個命名規則:
>
1.項目名:首字母大寫,其余小寫,用下劃線增加可讀性,如:Ui_test;
2.包名與模塊名:全部小寫字母;
3.類名:首字母大寫,其余小寫,多個單詞駝峰命名法;
4.方法(函數)名:全部小寫,多個單詞用下劃線分隔;
5.參數名:小寫單詞,如果與關鍵詞沖突,參數名前加上下劃線,比如_print;
6.變量:小寫,多個單詞用下劃線分隔;
7.常量:全部大寫,多個單詞用下劃線分隔;
3) 注釋
Python 使用 # 來進行 單行注釋,多行注釋 的話使用三引號,比如:
'''
這是
Python的
多行注釋
'''
4) print打印輸出與input輸入函數
學習一門新的編程語言,第一個程序基本都是打印Hello world,
把結果打印到屏幕上,是驗證代碼執行結果的最直觀體現,所以
有必要先學一波 print 和 input 的用法!
print():
1.可以輸出各種亂七八糟類型的數據直接轉成字符串打印輸出;
2.print默認會換行,如果不換行可以: print(xxx, end = "")
3.支持 格式化輸出,和C中的printf用法類似,逗號分隔前后改成%:
input():
從鍵盤讀入一個字符串,并自動忽略換行符,所有形式的輸入按字符串處理。
可以在括號里寫一些輸入的提示信息,比如: input("請輸入一個字符串:")
???輸出結果:???
5) help函數
這個就不用說了,很多編程語言都有的,可以用來查看某個 內置函數(BIF)
的相關用法的,比如help(print),會輸出這樣的結果:
6) dir函數
查看對象內所有屬性與方法,只需要把要查詢的對象添加到括號中即可,
比如定義一個類,然后用dir可以獲取所有的屬性與方法:
???部分輸出結果:???
7) 查看所有內置函數(BIF)
執行:print(dir(sys.modules['builtins'])) 可以打印出所有的內置函數。
8) 多個語句一行與一個語句多行
如果你想把多個語句寫到一行,可以使用; (分號)分隔;
有時語句可能太長,你可以使用\ (反斜杠)來銜接,
而在[] , {} , ()里的不需要使用反斜杠來銜接。
5.數據類型
1) 變量
Python3里定義一個變量非常簡單粗暴,直接一個 變量名 = 初值
賦值時就決定了變量的數據類型,變量名引用了數值的同時也引用
它的類型,如果不理解的話,看下例子就知道了,type可以查看
變量的數據類型(另外還要注意Python對大小寫敏感,區分大小寫!):
???輸出結果:???
另外Python中支持多個變量賦值,以下這兩種賦值寫法是正確的:
a = b = c = 1
a,b,c = 1,2,"Python"
對了,你還可以使用del關鍵字刪除對象的引用,但刪除后再調用
變量是會報錯的!
???輸出結果:
2) 數字(Mumber)
Python3中支持四種數字類型:int,float,complex(復數)
注:Python3中 int 不區分整形與長整形,整數的長度不受限制,
所以很容易進行大數計算。而除了十進制外的進制表示如下:
二進制0b,八進制0o,十六進制0x 開頭。
Python支持復數直接表示法,就是(a+bj)的形式,complex類的實例,
可以直接運算,比如:*a = 1 + 2j + 3 4j,輸出a,結果是:(1+14j)實數+虛數,除了a+bj,還可以用complex(a,b)表示,兩個都是
浮點型,可以調用.real獲得實部,.imag獲得虛部,abs()求復數
的模(√(a^2 + b^2)**)。
數字類型轉換:(Python文檔中,方括號[]括起來表示為可選)
函數
作用
int(x[,base])
將x轉換為一個整數,第二個參數是指定前面字符串的進制類型
float(x)
將x轉換到一個浮點數
complex(real [,imag])
創建一個復數
str(x)
將對象x轉換為字符串
repr(x)
將對象x轉換為表達式字符串
eval(str)
用來計算在字符串中的有效Python表達式,并返回一個對象
tuple(s)
將序列s轉換為一個元組
list(s)
將序列s轉換為一個列表
chr(x)
將一個整數轉換為一個字符
unichr(x)
將一個整數轉換為Unicode字符
ord(x)
將一個字符轉換為它的整數值
hex(x)
將一個整數轉換為一個十六進制字符串
oct(x)
將一個整數轉換為一個八進制字符串
bin(x)
將一個整數轉換為一個二進制字符串
數學函數:
函數
作用
abs(x)
返回數字的絕對值,如abs(-10) 返回 10
ceil(x)
返回數字的上入整數,如math.ceil(4.1) 返回 5
cmp(x, y)
如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1
exp(x)
返回e的x次冪(ex),如math.exp(1) 返回2.718281828459045
fabs(x)
返回數字的絕對值,如math.fabs(-10) 返回10.0
floor(x)
返回數字的下舍整數,如math.floor(4.9)返回 4
log(x)
如math.log(math.e)返回1.0,math.log(100,10)返回2.0
log10(x)
返回以10為基數的x的對數,如math.log10(100)返回 2.0
max(x1, x2,...)
返回給定參數的最大值,參數可以為序列。
min(x1, x2,...)
返回給定參數的最小值,參數可以為序列。
modf(x)
返回x的整數部分與小數部分,兩部分的數值符號與x相同,
整數部分以浮點型表示。
pow(x, y)
x的y次方
round(x [,n])
返回浮點數x的四舍五入值,如給出n值,則代表舍入到
小數點后的位數。
sqrt(x)
返回數字x的平方根,數字可以為負數,返回類型為實數,
如math.sqrt(4)返回 2+0j
3) 布爾類型(Bool)
用True和False來表示真假,也可以當做整數來對待,True為1,
False為0,但是不建議用來參與運算!
4) 列表(List)
類似于數組,有序,內容長度可變,使用中括號[]表示,元素間用逗號分隔,
元素的數據類型可以不一樣!用法示例如下(dir(list)可以查看所有的屬性與方法j):
(Tip:列表可嵌套,如果想訪問列表中的列表中的某個值可以寫多個[],比如:list1[1][2])
list1 = [1,2.0,"a",True] # 定義列表
print(list1[1]) # 通過[下標]訪問元素,從0開始,結果輸出:2.0
print(list1[1:3]) # 支持截取,比如這里的[1:3],結果輸出:[2.0, 'a']
print(list1[1:3:2]) # 還可以有第三個參數,步長,默認為1,結果輸出:[2.0]
print(list1[2:]) # 輸出結果:['a', True]
print(list1[-2]) # 負數的話從后面開始訪問,結果輸出:a
print(list1.index("a")) # 返回參數在列表中的位置,結果輸出:2
# 修改列表元素
list1[1] = 3.0 # 直接獲得元素后進行修改,此時列表元素:[1, 3.0, 'a', True]
# 添加元素
list1.append('Jay') # 追加一個元素,此時列表元素:[1, 2.0, 'a', True, 'Jay']
list1.insert(2,'pig') # 插入一個元素,此時列表元素:[1, 2.0, 'pig', 'a', True]
print(list1.pop()) # 移除最后一個元素,并返回元素的值,結果輸出:True
# 刪除元素
del list1[0] # 刪除索引位置的值,此時列表元素:[2.0, 'a', True]
list1.remove('a') # 刪除指定的元素值,此時列表元素:[1, 2.0, True]
# 其他(使用+號可以組合列表,*號可以重復列表)
print(list1+list1) # 輸出結果:[1, 2.0, 'a', True, 1, 2.0, 'a', True]
print(list1*2) # 輸出結果:[1, 2.0, 'a', True, 1, 2.0, 'a', True]
print('a' in list1) # 判斷列表中是否有此元素,輸出結果:True
print('b' not in list1) # 判斷原始中是不是沒有這個元素,輸出結果:True
for x in list: # 迭代遍歷列表
print(len(list1)) # 獲得列表長度,結果輸出:4
print(list1.count(1)) # 統計某個元素在列表中出現的次數,結果輸出:2,因為True的值也是1
max(list1) # 獲得列表中的元素最大值,列表元素類型需要為數字
min(list1) # 獲得列表中的元素最小值,列表元素類型需要為數字
list1.sort() # 對原列表元素進行排序,本地排序(會修改值),返回None,
# 只能比較數字!默認從小到大,從大到小可以用可選參數,括號里加上:
# key = lambda x:-1*x
list1.reverse() # 反轉列表元素,會修改列表,返回None
list2 = list1.copy() # 拷貝列表,重新開辟了內存空間!和等號賦值不一樣!
list(tuple) # 將元組或字符串轉換為列表
5) 元組(tuple)
受限的列表,元組中的元素不能修改,使用小括號()表示。
有一點要注意的是:當元組中只有一個元素,需要在元素后添加逗號,
否則會當做括號運算符使用!元組可以當做不能修改的參數傳遞給函數,
而且元組所占用的內存較小。使用的話,除了沒有修改元組元素的方法外,
其他的和列表的方法基本一致。
另外元組中的元素不能刪除,但是可以使用del語句來刪除整個元組,
不過比較少用,因為Python回收機制會在這個元組不再被使用時自動刪除
(和Java的gc有點像~) 還可以使用tuple(list)將字符串或列表轉換為元組。
??輸出結果:??
6) 字典(dict)
和列表,元組通過下標序列來索引元素不同,字典使用鍵值對的形式來存儲
數據,通過鍵來索引值,創建字典時,鍵不能重復,重復后面的會覆蓋!
因為鍵必須不可變,所以鍵可用數字,字符串或元組,但是不能用列表!
使用冒號:分割鍵與值,多個鍵值對用逗號,分隔;字典也是支持嵌套的!
用法示例如下:
dict1 = {} # 定義一個空字典
dict2 = {'a': 1, 'b': 2, 3: "c"} # 定義一個普通字典
dict4 = dict2.copy() # 淺復制一個字典
# 可以使用fromkeys創建并返回新的字典,有兩個參數,鍵和鍵對應的值
# 值可以不提供,默認None,不過有個小細節要注意,下面的例子輸出
# 的結果是:{1: ['a', 'b', 'c'], 2: ['a', 'b', 'c'], 3: ['a', 'b', 'c']}
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
dict3 = {}
dict3 = dict3.fromkeys(list1, list2)
print(dict3)
# 通過鍵查詢對應的值,如果沒有這個鍵會報錯TypeError,這里輸出結果:2
print(dict2['b'])
print(dict2.get("d")) # 通過get()方法查詢鍵對應的值,沒有的話會返回None
# 還可以加上一個默認的返回參數get(x,y)
print(dict2.setdefault("d")) # 和get()類似,如果找不到鍵的話會自動添加 鍵:None
print("d" in dict2) # 字典中是否有此鍵,這里輸出結果:False
print("d" not in dict2) # 字典中是否沒有此鍵,這里輸出結果:True
print(dict2.keys()) # 返回字典中所有的鍵,這里輸出結果:dict_keys(['a', 3, 'b'])
print(dict2.values()) # 返回字典中所有的值,這里輸出結果:dict_values([1, 'c', 2])
print(dict2.items()) # 返回字典中所有的鍵值對,這里輸出結果:
# dict_items([('a', 1), (3, 'c'), ('b', 2)])
# 修改鍵對應的值,此時字典元素:{3: 'c', 'a': 1, 'b': 'HaHa'}
dict2['b'] = 'HaHa'
dict2.update(b:'Pig') # 使用update方法可以更新鍵對應的值,不過鍵需要為字符串!
# 刪除字典元素
del(dict2['b']) # 刪除某個鍵值對,此時字典元素:{3: 'c', 'a': 1}
dict2.clear() # 移除字典中所有的鍵值對,此時剩下空字典:{}
del dict2 # 刪除整個字典,刪除后無法再重復引用!!!
print(dict2.pop('a')) # 根據鍵刪除對應的值,返回被刪除的值。
print(dict2.popitem()) # 刪除一個項,隨機,比如:('b', 2)
# 遍歷字典:
for d in dict2:
print("%s:%s" % (d, dict2.get(d)))
for (k,v) in dict2.items():
print("%s:%s" % (k, v))
7) 集合(set)
集合中的存儲的元素無序且不重復,所以你無法去索引某個具體的元素;
使用大括號{}包裹元素,逗號分隔,如果有重復的元素會被自動剔除!
另外有一點要注意的是,如果是創建空集合必須使用set(),而不能用{},
通過上面我們也知道了{}的話是直接創建一個空字典!
用法示例如下:
set1 = set() # 創建空集合
set2 = {1, 2, 3, 4, 5, 1} # 普通方式創建集合
print(set2) # 重復元素會被自動刪除,輸出結果:{1, 2, 3, 4, 5}
set3 = set('12345') # 字符串
print(set3) # 輸出:{'2', '5', '3', '4', '1'},集合元素無序
print(6 in set2) # 判斷集合中是否有此元素:輸出結果:False
print(6 not in set2) # 判斷集合中是否有此元素:輸出結果:True
set2.add("6") # 添加元素
print(set2) # 輸出結果:{1, 2, 3, 4, 5, '6'}
set2.remove(2) # 刪除元素,如果刪除的元素不存在會報錯
print(set2) # 輸出結果:{1, 3, 4, 5, '6'}
# 遍歷集合,輸出結果: 1 3 4 5 6
for data in set2:
print(data, end="\t")
# 使用frozenset()函數定義不可變集合
set4 = frozenset({1, 2, 3, 4, 5})
8) 字符串
Python里對處理字符串可是日常,熟練掌握字符串的處理非常重要。
可以使用單引號('')或者雙引號("")來修飾字符串,
如果想讓字符串包含換行縮進等格式時,可以使用三括號('''''')
來修飾,一般要打印段落文字的時候可以用這個。
另外,字符串定義后就不能修改元素了,比如下面str1[0] = 'x'是會報錯的,
只能通過+,*,分片等方式進行拼接,間接得到相同的字符串內容,不過卻不是原來
的字符了,變量指向了新的字符串,而舊的會被py的回收機制回收掉!
訪問字符串:
str1 = "Hello Python"
print(str1[3]) # 輸出結果:l
print(str1[2:]) # 輸出結果:llo Python
print(str1[2:5]) # 輸出結果:llo
print(str1[2:10:2]) # 輸出結果:loPt
print(str1[0:8] + str1[8:]) # 輸出結果:Hello Python
str2 = str1[6:] * 3
print(str2) # 輸出結果:PythonPythonPython
轉義字符:
轉義字符
作用
轉義字符
作用
轉義字符
作用
行尾的\
續行符
\\
反斜杠
\'
單引號
\a
響鈴
\b
退格
\e
轉義
\000
空
\n
換行
\v
縱向制表符
\t
橫向制表符
\r
回車
\f
換頁
\o
八進制數代表字符
\x
十六進制數代表字符
各種內置方法:
方法名
作用
capitalize()
把字符串的第一個字符改為大寫
casefold()
把整個字符串的所有字符改為小寫
center(width)
將字符串居中,并使用空格填充至長度width的新字符串
count(sub[,start[,end]])
返同sub在字符申里邊出現的次數,
start和end參數表示范圍,可選
encode(encoding= 'utf-8 ',errors='strict')
以encoding指定的編碼格式對字符串進行編碼
endswith(sub[,start[,end]])
檢查字符串是否以sub 子字符串結束,如果是返回True,
否則返回False。start和end參數表示范圍,可選
expandtabs([tabsize= 8])
把字符串中的tab符號(\t)轉換為空格,如不指定參數,
默認的空格數是tabsize=8
find(sub[,start[,end]])
檢測sub是否包含在字符串中,如果有則返回索引值,
否則返回-1,start和end參數表示范圍,可選
index(sub[,start[,end]])
跟find方法一樣,不過如果sub不在string中會產生一個異常
isalnum()
如果字符串中至少有一個字符,并且所有字符都是
字母或數字則返回True,否則返回False
isalpha()
如果字符串至少有一個字符串,并且所有字符都是
字母則返回True,否則返回False
isdecimal()
如果字符串只包含十進制數字則返回True,否則返回False
isdigit()
如果字符串只包含數字則返回True,否則返回False
islower()
如果字符串中至少包含一個區分大小寫的字符,并且這些字符
都是小寫,則返回True,否則返回False
isnumeric()
如果字符串中只包含數字字符,則返回True,否則返回False
isspace()
如果字符串中只包含空格,則返回True,否則返回False
istitle()
如果字符串是標題化(所有單詞大寫開頭,其余小寫),
則返回True,否則返回False
isupper()
如果字符串中至少包含一個區分大小寫的字符,并且這些
字符都是大寫,則返回True,否則返回False
join(sub)
以字符串作為分隔符,插入到sub中所有的字符之間,使用+去拼接大量
字符串的時候是很低效率的,因為加號拼接會引起內存賦值一級垃圾回收
操作,此時用join來拼接效率會高一些,比如: ''.join(['Hello','Python'])
ljust(width)
返回一個左對齊的字符串,并使用空格填充至長度為width的新字符串
lower()
轉換字符串所有大寫字符為小寫
lstrip()
去除字符串左邊的所有空格
partition(sub)
找到子字符串sub,把字符串分割成3元組(前,pre,后)
如果字符串中不包含則返回('原字符串','','')
replace(old, new[,count])
把字符串中的old子字符串替換成new,如果count指定,
則替換次數不超過count次
rfind(sub[,start[,end]])
和find()方法類似,不過是從右開始查找
rindex(sub[,start[,end]])
和index()方法類似,不過是從右開始查找
rjust(width)
返回一個右對齊的字符串,并使用空格填充至長度為width的新字符串
rpartition(sub)
類似于partition(),不過是從右邊開始查找
rstrip()
刪除字符串末尾的空格
split(sep=None,maxsplit=-1)
不帶參數默認是以空格為分隔符切片字符串,如果maxspli參數t
右設置,則僅分隔maxsplit個子字符串,返回切片后的子字符串拼接的列表
splitlines([keepends])
按照'\n'分隔,返回一個包含各行作為元素的列表,如果keepends參數
指定,則返回前keepends行
startswith(prefix[,start[,end]])
檢查字符串是否以prefix開頭,是則返回True,否則返回False。
start和end參數可以指定范圍檢查,可選
strip([chars])
刪除字符串前邊和后邊所有的空格,chars參數可定制刪除的字符串,可選
swapcase()
反轉字符串中的大小寫
title()
返回標題化(所有的單詞都是以大寫開始,其余字母小寫)的字符串
translate(table)
按照table的規則(可由str.maketrans('a','b')定制)轉換字符串中的字符
upper()
轉換字符串中所有的小寫字符為大寫
zfill(width)
返回長度為width的字符串,原字符串右對齊,前邊用0填充
字符串格式化:
其實就是format方法的使用而已,示例如下:
# 位置參數
str1 = "{0}生{1},{2}{3}!".format("人","苦短","我用","Python")
print(str1) # 輸出結果:人生苦短,我用Python!
# 關鍵字參數
str1 = "{a}生{c},{b}ozvdkddzhkzd!".format(a = "人", c = "苦短",b = "我用",d = "Python")
print(str1) # 輸出結果:人生苦短,我用Python!
# 位置參數可以與關鍵字參數一起使用,不過位置參數需要在關鍵字參數前,否則會報錯!
# 另外還有個叫替換域的東西,冒號代表格式化符號開始,比如下面的例子:
str1 = "{0}:{1:.4}".format("圓周率", 3.1415926)
print(str1) # 輸出結果:圓周率:3.142
格式化操作符:%,這個就不說了,和上面print()那里的一致!
9) 運算符
算術操作符:(+ - * / % **(冪,次方) //(地板除法,舍棄小數))
print("3 + 7 = %d" % (3 + 7)) # 輸出結果: 3 + 7 = 10
print("3 - 7 = %d" % (3 - 7)) # 輸出結果: 3 - 7 = -4
print("3 * 7 = %d" % (3 * 7)) # 輸出結果: 3 * 7 = 21
print("7 / 3 = %f" % (7 / 3)) # 輸出結果: 7 / 3 = 2.333333
print("7 %% 3 = %d" % (7 % 3)) # 輸出結果: 7 % 3 = 1
print("3 ** 6 = %d" % (7 ** 3)) # 輸出結果: 3 ** 6 = 343
print("3 // 6 = %f" % (7 // 3)) # 輸出結果: 3 // 6 = 2.000000
比較運算符:(== != > < >= <=)
賦值運算符:(== += -= *`=** **/=** **%=** **=` //=)
位運算符:(&(按位與) |(按位或) ^(異或,不同為1) ~(取反) << >>)
邏輯運算符:(and or not)
成員運算符:(in not in)
身份運算符(判斷是否引用同一個對象):(is is not)
運算符優先級:
**(指數) ??>?? ~ + -(取反,正負號) ??>?? * / % //(乘除,求余,地板除) ??>?? << >>(左右移)
> ?? &(按位與) ??>??^ |(異或,按位或)??> ??< <= > >=(比較運算符) ??>??等于運算符??> ??賦值運算符
>??身份運算符??>??成員運算符??>??邏輯運算符
10) 日期時間
日期時間并不屬于數據結構,只是覺得很常用,索性也在這里把用法mark下~
以來的兩個模塊是:time 和 datetime,詳細用法示例如下:
import time, datetime
# 獲取當前時間
moment = time.localtime()
print("年:%s" % moment[0])
print("月:%s" % moment[1])
print("日:%s" % moment[2])
print("時:%s" % moment[3])
print("分:%s" % moment[4])
print("秒:%s" % (moment[5] + 1))
print("周幾:%s" % (moment[6] + 1))
print("一年第幾天:%s" % moment[7])
print("是否為夏令時:%s" % moment[8])
# 格式化時間(這里要注意strftime和strptime是不一樣的!!!)
moment1 = time.strftime('%Y-%m-%d %H:%M:%S')
moment2 = time.strftime('%a %b %d %H:%M:%S %Y', time.localtime())
moment3 = time.mktime(time.strptime(moment2, '%a %b %d %H:%M:%S %Y'))
print(moment1) # 輸出結果:2017-12-02 11:08:02
print(moment2) # 輸出結果:Sat Dec 02 11:08:02 2017
print(moment3) # 輸出結果:1512184082.0 日期轉換為時間戳
# 獲得當前時間戳
print(time.time()) # 輸出結果:1512185208.0942981
# 獲得當前時間(時間數組,還需strftime格式化下)
print(datetime.datetime.now()) # 輸出結果:2017-12-02 11:34:44.726843
# 時間戳轉換為時間
# 方法一:(輸出結果:2017-12-02 11:08:02)
moment4 = 1512184082
moment5 = time.localtime(moment4) # 轉換成時間數組
print(time.strftime('%Y-%m-%d %H:%M:%S', moment5)) # 格式化
# 方法二:
moment6 = datetime.datetime.utcfromtimestamp(moment4)
print(moment6) # 直接輸出:2017-12-02 03:08:02
moment7 = moment6.strftime('%a %b %d %H:%M:%S %Y')
print(moment7) # 格式化后輸出:Sat Dec 02 03:08:02 2017
# 延遲執行
time.sleep(秒)
6.流程控制
1) if條件判斷
python中沒有switch-case,另外使用了 elif 代替了else if
每個條件后需要跟一個冒號(:),通過縮放來劃分代碼塊,
嵌套的時候要注意!使用示例如下:
???輸出結果:
另外,如果條件成立,你又不想做任何事情,可以直接使用pass空語句
2) while循環
python中沒有do-while,同樣要注意冒號和縮放!
可以搭配else使用,還有無限循環這種東西:while True:
使用下面的break關鍵字可以跳出循環。
使用示例如下:
???輸出結果:
3) for循環
和C或者Java那種for循環不同,并不能直接寫 for(int a = 0;a < 100;a++)
使用示例如下:
輸出結果:
4) break,continue,else
break跳出循環;continue跳過余下操作直接進入下一次循環;
else也可以使用在循環,for循環條件不成立時執行,如果先break的話不會執行!
5) 條件表達式(簡化版的if-else)
a = x if 條件 else y
6) 斷言
當assert關鍵字后面的判斷條件為假的時候,程序自動崩潰并拋出AssertionErro異常,
一般在測試程序的時候才會用到,要確保某個條件為真程序才能正常工作的時候使用~
7) 迭代器與生成器
迭代器:用于訪問集合,是一種可以記住遍歷位置的對象,會從第一個元素
開始訪問,直到結束,兩個基本的方法:iter()和next()
輸出結果:
生成器
應該叫生成器函數吧,一種特別的函數,用yield來返回值,
調用時會返回一個生成器對象,本質上還是迭代器,只是更加簡潔,
yield對應的值在函數調用的時候不會立即返回,只有去調用next()
方法的時候才會返回,使用for x in xxx的時候其實調用的還是next()方法,
最簡單的使用示例如下:
???輸出結果:???
如果你用type()方法查下,會發現返回的對象類型是:``
相比起迭代器,生成器更加簡潔優雅,最經典的例子就是實現斐波那契數列:
def func(n):
a, b = 0, 1
while n > 0:
n -= 1
yield b
a, b = b, a + b
for i in func(10):
print(i, end="\t")
# 輸出結果:1 1 2 3 5 8 13 21 34 55
7.函數
對于一些重復使用的代碼塊,我們可以把他抽取出來寫成一個函數。
1) 函數定義
使用 def關鍵字 修飾,后接函數名與圓括號(傳入參數),
使用 return關鍵字 返回值,不寫的話默認返回 None值,
Python可以動態確定函數類型,返回不同的類型的值,可以利用
列表打包多種類型的值一次性返回,也可以直接用元組返回多個值;
另外函數參數如果有多個的話,可以用逗號隔開。
還有一個建議是:在函數第一行語句可以選擇性地使用文檔字符串用于存放
函數說明,直接用三引號注釋包括即可,通過help方法可以拿到!
2) 形參與實參
定義函數時的參數是形參,調用時傳入的是實參;
3) 關鍵字參數
參數有多個的時候,怕參數混淆傳錯,可以在傳入的時候
指定形參的參數名,比如: show(a = "a", b = "b")這樣。
4) 默認參數
定義的形參時候賦予默認初值,調用時就可以不帶
參數去調用函數,比如:def sub(a = "1", b = "2"),調用時直接
什么都傳sub()或者傳入一個參數sub(3)都可以,還可以配合
關鍵字參數指定傳入的是哪個參數。
5) 可變參數
有時傳入的函數參數數目可能是不固定的,比如,要你
計算一組值的和,具體有多少個數字不知道,此時就可以用可變參數了。
只需要在參數前加上*號(其實是把數據打包成了元組),就代表這個
參數是可變參數;如果有多個參數,寫在可變參數后的參數要用
關鍵字參數指定,否則會加入可變參數的范疇!!!有打包自然有解包,如果想把列表或元組當做可變參數傳入,需要在傳入的時候
在實參前加上*號!另外,如果想把參數打包成元組的方式的話,
可以使用兩個星號(``**)修飾~
6) 全局變量與局部變量
全局變量就是定義為在最外部的,可以在函數內部進行訪問但不能直接修改;
局部變量就是定義在函數內部的,而在函數外部無法訪問的參數或變量;
局部變量無法在外部訪問的原因:
Python在運行函數時,會利用棧(Stack)來存儲數據,執行完
函數后,所有數據會被自動刪除。
函數中無法修改全局變量的原因:
當試圖在函數里修改全局變量的值時,Python會自動在函數內部新建一個
名字一樣的局部變量代替。如果硬是要修改,可以在函數內部使用
global關鍵字 修飾全局變量,但是不建議這樣做,會使得程序
維護成本的提高。
7) 內部函數
其實就是函數嵌套,一個函數里嵌套另一個函數,需要注意一點:
內部函數的作用域只在內部函數的直接外部函數內,外部是
無法調用的,如果調用會報錯的。
8) 閉包
Python中的閉包:如果在一個外部函數中,對外部作用域(非全局)的變量
進行引用,那么內部函數就被認為是閉包。簡單的例子如下:
??? 輸出結果:???
不能在外部函數以外的地方調用內部函數,會報方法名未定義。
另外,內部函數也不能直接修改外部函數里的變量,會報UnboundLocalError錯誤!
和前面函數里修改全局變量的情況一樣,如果硬是要修改的話
可以把外部函數中的變量間接通過容器類型來存放,或者使用
Python3 中提供的nolocal關鍵字修飾修改的變量。例子如下:
??? 輸出結果:??? 400
9) lambda表達式
在Python中可以使用lambda關鍵字來創建匿名函數,直接返回一個函數對象,
不用去糾結起什么名字,省了定義函數的步驟,從而簡化代碼的可讀性!
簡單的對比大小lambda表達式例子如下:
big = lambda x, y: x > y
print("第一個參數比第二個參數大:%s" % big(1, 2))
# 輸出結果:第一個參數比第二個參數大:False
10) 遞歸
其實就是函數調用自身,最簡單的遞歸求和例子如下:
def sum(n):
if n == 1:
return 1
else:
return n + sum(n - 1)
print("1到100的求和結果是: %d" % sum(100))
# 輸出結果:1到100的求和結果是: 5050
8.異常處理
1) 語法錯誤與運行異常區分
語法錯誤是連編譯器那關都過不了的錯誤,比如if后漏掉:冒號,跑都跑不起來;
運行異常則是程序跑起來后,因為程序的業務邏輯問題引起的程序崩潰,比如除以0;
2) Python中的常見異常
異常
描述信息
AssertionError
斷言語句失敗
AttributeError
嘗試訪問未知的對象屬性
IndexError
索引超出序列的范圍
keyError
字典中查找一個不存在的Key
NameError
嘗試訪問一個不存在的變量
OSError
操作系統產生的異常,比如FileNotFoundError
SyntaxError
Python語法錯誤
TypeError
不同類型間的無效操作
ZeroDivisionError
除數為0
IOError
輸入輸出錯誤
ValueError
函數傳參類型錯誤
3) 異常捕獲
try-expect-else語句,try-finally語句
# 1.最簡單的,try捕獲了任何異常,直接丟給except后的代碼塊處理:
try:
result = 1 / 0
except:
print("捕獲到異常了!") # 輸出:捕獲到異常了!
# 2.捕獲特定類型:
try:
result = 1 / 0
except ZeroDivisionError:
print("捕獲到除數為零的錯誤") # 輸出:捕獲到除數為零的錯誤
# 3.針對不同的異常設置多個except
try:
sum = 1 + '2'
result = 1 / 0
except TypeError as reason:
print("類型出錯:" + str(reason))
except ZeroDivisionError as reason:
print("除數為0:" + str(reason))
# 輸出:類型出錯:unsupported operand type(s) for +: 'int' and 'str'
# 4.對多個異常統一處理
try:
result = 1 / 0
sum = 1 + '2'
except (TypeError, ZeroDivisionError) as reason:
print(str(reason)) # 輸出:division by zero
# 5.當沒有檢測到異常時才執行的代碼塊,可以用else
try:
result = 4 / 2
except ZeroDivisionError as reason:
print(str(reason))
else:
print("沒有發生異常,輸出結果:%d" % result)
# 輸出:沒有發生異常,輸出結果:2
# 6.無論是否發生異常都會執行的一段代碼塊,比如io流關閉,
# 可以使用finally子句,如果發生異常先走except子句,后走finally子句。
try:
result = 4 / 2
except ZeroDivisionError as reason:
print(str(reason))
else:
print("沒有發生異常,輸出結果:%d" % result)
finally:
print("無論是否發生異常都會執行~")
# 輸出結果:
# 沒有發生異常,輸出結果:2
# 無論是否發生異常都會執行~
4) 拋出異常
使用raise語句可以直接拋出異常,比如raise TypeError(異常解釋,可選)
5) 上下文管理-with語句
當你的異常捕獲代碼僅僅是為了保證共享資源(文件,數據等)的唯一分配,
并在任務結束后釋放掉它,那么可以使用with語句,例子如下:
try:
with open('123.txt', "w") as f:
for line in f:
print(line)
except OSError as reason:
print("發生異常:" + str(reason))
# 輸出結果:發生異常:not readable
6) sys.exc_info 函數
除了上面獲取異常信息的方式外,還可以通過sys模塊的exc_info() 函數獲得:
示例如下:
# 輸出結果依次是:異常類,類示例,跟蹤記錄對象
try:
result = 1 / 0
except:
import sys
tuple_exception = sys.exc_info()
for i in tuple_exception:
print(i)
# 輸出結果:
#
# division by zero
#
9.文件存儲
1) open函數與文件打開模式
Python中讀寫文件非常簡單,通過open()函數 可以打開文件并
返回文件對象使用help命令可以知道,open函數有好幾個參數:
作為初學者,暫時了解前兩個參數就夠了:
file參數:文件名,不帶路徑的話會在當前文件夾中查找;
mode:打開模式,有以下幾種打開方式:
模式
作用
r
只讀模式打開,默認
w
寫模式打開,若文件存在,先刪除,然后重新創建
a
追加模式打開,追加到文件末尾,seek()指向其他地方也沒用,文件不存在,自動創建
b
二進制模式打開
t
文本模式打開,默認
+
可讀寫模式,可配合其他模式使用,比如r+,w+
x
如果文件已存在,用此模式打開會引發異常
U
通用換行符支持
2) 文件對象的方法
函數
作用
close()
關閉文件,關閉后文件不能再進行讀寫操作
read(size=-1)
從文件讀取指定的字節數,如果未設置或為負數,讀取所有
next()
返回文件下一行
readline()
讀取整行,包括換行符'\n'
seek(offset, from)
設置當前文件指針的位置,從from(0文件起始位置,1當前位置,
2文件末尾)偏移offset個字節
tell()
返回文件的當前位置
write(str)
將字符串寫入文件
writelines(seq)
寫入一個序列字符串列表,如果要換行,需要自己加入每行的換行符
3) 使用例子
# 讀取123.txt文件里的內容打印,同時寫入到321.txt中
try:
f1 = open("321.txt", "w")
with open("123.txt", "r") as f2:
for line in f2:
print(line, end="")
f1.write(line)
except OSError as reason:
print("發生異常" + str(reason))
finally:
f1.close() # 用完要關閉文件,f2不用是因為用了with
輸出結果:
????
4) OS模塊中關于文件/目錄的常用函數
需要導入os模塊,使用的時候需加上模塊引用,比如os.getcwd()
函數
作用
getcwd()
返回當前工作目錄
chdir(path)
改變當前工作目錄
listdir(path='.')
不寫參數默認列舉當前目錄下所有文件和文件夾,'.'當前目錄,'..'上一層目錄
mkdir(path)
創建文件夾,若存在會拋出FileExistsError異常
mkdirs(path)
可用于創建多層目錄
remove(path)
刪除指定文件
rmdir(path)
刪除目錄
removedirs(path)
刪除多層目錄
rename(old,new)
重命名文件或文件夾
system(command)
調用系統提供的小工具,比如計算器
walk(top)
遍歷top參數指定路徑下所有子目錄,返回一個三元組(路徑,[包含目錄],[包含文件])
curdir
當前目錄(.)
pardir
上一節目錄(..)
sep
路徑分隔符,Win下是'\',Linux下是'/'
linesep
當前平臺使用的行終止符,win下是'\r\n',Linux下是'\n'
name
當前使用的操作系統
os.path模塊(文件路徑相關)
函數
作用
dirname(path)
獲得路徑名
basename(path)
獲得文件名
join(path1[,path2[,...]])
將路徑名與文件名拼接成一個完整路徑
split(path)
分割路徑與文件名,返回元組(f_path, f_name),如果完全使用目錄,
它也會將最后一個目錄作為文件名分離,且不會判斷文件或目錄是否存在
splitext(path)
分隔文件名與擴展名
getsize(file)
獲得文件大小,單位是字節
getatime(file)
獲得文件最近訪問時間,返回的是浮點型秒數
getctime(file)
獲得文件的創建時間,返回的是浮點型秒數
getmtime(file)
獲得文件的修改時間,返回的是浮點型秒數
exists(path)
判斷路徑(文件或目錄)是否存在
isabs(path)
判斷是否為決定路徑
isdir(path)
判斷是否存在且是一個目錄
isfile(path)
判斷是否存在且是一個文件
islink(path)
判斷是否存在且是一個符號鏈接
ismount(path)
判斷是否存在且是一個掛載點
samefile(path1,path2)
判斷兩個路徑是否指向同一個文件
wenji
10.類與對象
1) 最簡單的例子
PS:Python中沒有像其他語言一樣有public或者private的關鍵字
來區分公有還是私有,默認公有,如果你想定義私有屬性或者函數,
命名的時候在前面加上兩下劃線__即可,其實是偽私有,內部
采用的是名字改編技術,改成了_類名__私有屬性/方法名,比如
下面調用people._Person__skill,是可以訪問到私有成員的!
類中的屬性是靜態變量。
輸出結果:
2) __init__(self) 構造方法
實例化對象的時候會自動調用,當你想傳參的時候可以用它~
輸出結果:
3) 繼承
規則如下:
1.繼承寫法: class 子類(父類):
2.子類可以繼承父類的所有屬性與方法;
3.子類定義與父類同名的屬性與方法會自動覆蓋;
4.重寫時如果想調用父類的同名方法可以使用super()函數. 方法名調用;
Python支持多繼承,多個父類用逗號隔開,子類可同時繼承多個父類的
屬性與方法多繼承的時候如果父類們中有相同的方法,調用的順序是
誰在前面先調用那個父類中的方法,比如有class Person(Name, Sex,Age),
三個父類里都有一個show的方法,那么子類調用的是Name里的show()!
如果不是得用多繼承不可的話,應該盡量避免使用它,有時會出現
一些不可遇見的BUG。
還有一種叫組合的套路,就是在把需要用到的類丟到組合類中
實例化,然后使用,比如把Book,Phone,Wallet放到Bag里:
輸出結果:
4) 與對象相關的一些內置函數
函數
作用
issubclass(class, classinfo)
如果第一個參數是第二個參數的子類,返回True,否則返回False
isinstance(object, classinfo)
如果第一個參數是第二個參數的實例對象,返回True,否則返回False
hasattr(object, name)
測試一個對象中是否有指定的屬性,屬性名要用引號括著!
getattr(object, name, [,default])
返回對象的指定屬性值,不存在返回default值,沒設會報ArttributeError異常
setattr(object, name, value)
設置對象中指定屬性的值,屬性不存在會新建并賦值
delattr(object, name)
刪除對象中的指定屬性的值,不存在會報報ArttributeError異常
property(fget,fset,fdel,doc)
返回一個可以設置屬性的屬性
11.模塊
1) 導入模塊
保存為.py后綴的文件都是一個獨立的模塊,比如有a.py和b.py文件,
你可以在a中import b,然后就可以使用b.py中的函數了。
模塊導入規則4.1 導包處就寫得詳細了,此處就不重復描述了。
2) 指定模塊
導入其他模塊的時候,測試部分的代碼也會執行,可以通過
__name__告訴Python該模塊是作為程序運行還是導入到其他程序中。
作為程序運行時該屬性的值是__main__,只有單獨運行的時候才會執行。
比如:
if __name__ == '__main__':
test()
3) 搜索路徑
Python模塊的導入會有一個路徑搜索的過程,如果這些搜索路徑都找不到的話,
會報ImportError,可以通過打印sys.path可以看到這些搜索路徑,比如我的:
如果你的模塊都不在這些路徑里,就會報錯,當然也可以通過
sys.path.append("路徑") 把路徑添加到搜索路徑中!
4) 下載安裝第三方庫
方法一:Pycharm直接安裝
File -> Default Settings -> Project Interpreter -> 選擇當前Python版本
可以看到當前安裝的所有第三庫,點+號進入庫搜索,在搜索頁找到想要的
庫后勾選點擊Install Package即可,點-號可以卸載不需要的庫。
方法二:命令行使用pip命令安裝
pip在Python3里就自帶了,在Python安裝目錄的Scripts文件夾下,
win上需要配置下環境變量才能使用:
Path后面加上這個路徑即可:
pip install 庫名 # 安裝
python3 -m pip install 庫名 # 作用同上,可以區分python2和python3而已
pip install --upgrade pip # 更新pip
pip uninstall 庫名 # 卸載庫
pip list # 查看已安裝庫列表
5) 讓別人使用你的模塊
當你開始學爬蟲,電腦會慢慢多很多妹子圖,別問我為什么...
一些小伙伴看到會問你拿U盤拷,授之以魚不如授之以漁,直接把
自己寫的爬小姐姐的Py文件讓他自己跑,不更好~讓他裝玩Python3
配置好環境變量,直接命令行執行Python xxx.py是會報模塊找
不到的,你的小伙伴僅僅是對小姐姐有興趣,對Py學習沒什么
興趣,你不可能讓他pip命令一個個裝,可不可以導出一個依賴
文件的東西,執行以下自動安裝模塊呢?答案肯定是可以的:
先pip命令安裝一波:pipreqs:pip install pipreqs
安裝完后打開終端,cd到需要導出的項目,鍵入:
pipreqs 導出到哪個目錄
就可以導出一個requirements.txt文件了,文件里就是你項目
用到的需要另外安裝的Py庫了,把這個文件發給你的小伙伴,讓他
命令行執行:
pip install -r requirements.txt
運行后把庫裝上就基本:
另外,如果是你想把自己Python環境里的所有包都遷移到另一臺電腦
可以使用:
pip freeze > requirements.txt
結語
呼,歷時兩周,總算把Python的基礎知識過了一遍,當然肯定是會有遺漏的
后面想到再補上吧,擼基本知識是挺乏味的,期待后續爬蟲學習~
總結
以上是生活随笔為你收集整理的python bif_小猪的Python学习之旅 —— 1.基础知识储备的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cocos2d-x地图随精灵无限滚动与边
- 下一篇: python使用numba库实现gpu加