引言:(文章比較長,建議看目錄按需學習~)html
之前剛學編程的時候就對Python略有耳聞,不過學校只有C,C++,Java,C#。 和PHP有句**"PHP是最好的語言"** 這種家喻戶曉的騷話同樣,Python也有 "人生苦短,我用Python"。而接觸Python這個詞最多的場合就是在一些技術羣裏, 有些大佬張嘴動不動就說什麼Py交易,做爲潛伏在羣裏的開發萌新的我每次都 會忍不住會發出這樣的感慨:python
而真正接觸了下Python是在上家公司,當時老大讓我寫個腳本去下載 倉庫裏最近打包的apk,當時東湊湊西湊湊最後總算拼成了一個可運行 的py文件,由於不瞭解Python裏的數據結構,所有用的字符串變量, 後面被老大教育了一番才知道有元組這種東西。由於自己作Android的, Python用到的場合很少,加之以爲Kotlin有點意思,就沒去研究Python了。mysql
前段時間,手頭的事作得差很少了,無聊四處張望時,看到隔壁後臺 小哥迅雷瘋狂下載東西,建文件夾,粘貼複製,不知道還覺得他在給 小電影分類呢,後來一問才知道,運營讓他把服務器上全部的音頻 文件下下來,而後根據對應的類別下到對應文件夾,因此他作的事情 就是:迅雷批量下載過歌曲 -> 看mysql歌曲的分組 -> 建文件夾 -> 粘貼複製歌曲到這個文件夾下,咋一看,流程挺簡單的,然而有 4700多首歌,幾百個目錄,這樣慢慢搞怕是要搞幾天,並且常時間 機械化的重複某項工做,很容易出錯。看着一臉絕望的後臺小哥:git
於心不忍,決定寫個py腳原本拯救他,腦子裏也有了程序的大概邏輯:github
邏輯挺簡單明瞭的,然而各類坑,最後折騰了一天才能弄出來 遇到了下面這些問題:sql
當看到全部文件都下載到了對應的位置,一種油然而生的成就感, 比起寫APP每天畫界面,請求,解析數據,顯示數據,有意思太多, 畢竟學習開發興趣很重要,索性從零開始學習下Python吧,越學越以爲:編程
理由上班時的閒暇時間,歷時兩週總算是把基礎知識的東西過了 一遍,遂有此文,畢竟初學者,有些地方可能理解有誤,望看到 的大佬不吝賜教,文中大部份內容摘自: 《Python 3 教程》與《小甲魚的零基礎入門學習Python》 有興趣的能夠閱讀下這兩本書~ 本文不是入門教程啊,徹底沒有編程經驗的不建議閱讀! 徹底小白能夠看下這本:《編程小白的第一本Python入門書》api
[TOC]數組
!!!Python 3的語法 不徹底兼容 Python 2的語法!!!bash
菜逼剛學Python沒多久,不敢大聲嗶嗶,最直接緣由: Python 3默認使用utf-8,在處理中文的時候能夠 減小不少編解碼的問題,而Python 2默認使用ascii。
另外的緣由:與時俱進,IT行業發展那麼迅速,徹底過渡只是時間問題; 舉個例子:Android Studio剛出的沒多久的時候,各類說卡啊,垃圾, 只能開一個項目等各類嫌棄,不如Eclipse好用;然而如今開發Android 仍是用Eclipse的都是會被歧視一波的,另外官方已經肯定Python 2.7會 在2020年退休。So:人生苦短,我用Python3。
並且Python 2.7預計會在2020年退休
更多比較的文章可見:
Python2.x與3.x版本區別 Python2orPython3 Python3.x和Python2.x的區別
官網下載:www.python.org/downloads/, 本身選擇須要的版本與操做系統。
傻瓜式下一步就好,記得勾選Add Python x.x to Path!勾選 了你裝完就不用本身去配置環境變量,安裝完畢後打開CMD輸入: python3 -V 能查看到安裝的Python版本說明安裝成功, 若是提示錯誤:python3不是內部或外部命令之類的話,恭喜你 能夠百度下:Python3環境變量配置 了~
方法一:官網下安裝包,傻瓜下一步; 方法二:若是有裝Homebrew,終端輸入:brew install Python3 安裝便可。
其實在安裝完Python後就能夠進行Python編程了,直接命令行輸入python3, 就可使用自帶的IDLE進行開發了;又或者直接用Sublime Text或NotePad++ 這類代碼查看工具直接編寫代碼,而後保存成後綴爲.py的文件,而後python3 執行這個py文件就能夠了。
雖然能夠,可是挺不方便的,好比縮進問題,Python經過縮進來表示代碼塊, 代碼一多,某一行沒有正確的使用縮進,結果可能與你預期的相差甚遠。 智能提示,方便的依賴庫管理等,這兩個就不用說了吧,具體的還得你本身體會。
官網下載:www.jetbrains.com/pycharm/dow… 下載Professional版本,傻瓜式安裝,打開後會彈出註冊頁面, 勾選License server,在License server address輸入註冊服務器, 網上搜不少,而後就能夠愉快的進行py開發了。
軟件的基本使用也很是簡單,Jetbrains的IDE都是差很少的~ 有一點要注意的地方是,若是你想切換項目依賴的Python版本號的話: 打開設置(Preference或settings),修改便可:
有時項目中須要引入其餘模塊或者模塊中的某個函數,須要用到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 這樣就能夠了。
複製代碼
在對變量或者方法名這些標識符進行命名的時候,須要注意,不可以 與Python中的關鍵字相同,經過keyword.kwlist能夠查詢全部的關鍵字: 須要import keyword模塊哦~
除了不能與與關鍵字相同外,標識符的命名規則: 由字母,數字和下劃線組成,且首字符必須爲字母或下劃線, Python對大小寫敏感;關於命名規範的問題,沒有什麼 強制規定,整個項目保持統一就好,附上網上找的一個命名規則:
Python 使用 # 來進行 單行註釋,多行註釋 的話使用三引號,好比:
''' 這是 Python的 多行註釋 '''
複製代碼
學習一門新的編程語言,第一個程序基本都是打印Hello world, 把結果打印到屏幕上,是驗證代碼執行結果的最直觀體現,因此 有必要先學一波 print
和 input
的用法!
print():
格式化輸出
,和C中的printf用法相似,逗號分隔先後改爲**%**:
input():
從鍵盤讀入一個字符串,並自動忽略換行符,全部形式的輸入按字符串處理。 能夠在括號裏寫一些輸入的提示信息,好比: input("請輸入一個字符串:")
這個就不用說了,不少編程語言都有的,能夠用來查看某個 內置函數(BIF)
的相關用法的,好比help(print),會輸出這樣的結果:
查看對象內全部屬性與方法,只須要把要查詢的對象添加到括號中便可, 好比定義一個類,而後用dir能夠獲取全部的屬性與方法:
執行:print(dir(sys.modules['builtins'])) 能夠打印出全部的內置函數。
若是你想把多個語句寫到一行,可使用**;
** (分號)分隔; 有時語句可能太長,你可使用**\
** (反斜槓)來銜接, 而在**[] , {} , ()**裏的不須要使用反斜槓來銜接。
Python3裏定義一個變量很是簡單粗暴,直接一個 變量名 = 初值 賦值時就決定了變量的數據類型,變量名引用了數值的同時也引用 它的類型,若是不理解的話,看下例子就知道了,**type
**能夠查看 變量的數據類型(另外還要注意Python對大小寫敏感,區分大小寫!):
另外Python中**支持多個變量賦值
**,如下這兩種賦值寫法是正確的:
a = b = c = 1
a,b,c = 1,2,"Python"
複製代碼
對了,你還可使用**del
關鍵字刪除對象的引用**,但刪除後再調用 變量是會報錯的!
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 |
用**True
和False
**來表示真假,也能夠當作整數來對待,True爲1, False爲0,可是不建議用來參與運算!
相似於數組,有序,內容長度可變,使用中括號[]表示,元素間用逗號分隔, 元素的數據類型能夠不同!用法示例以下(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) # 將元組或字符串轉換爲列表
複製代碼
受限的列表,元組中的元素不能修改,使用小括號()表示。 有一點要注意的是:當元組中只有一個元素,須要在元素後添加逗號, 不然會當作括號運算符使用!元組能夠當作不能修改的參數傳遞給函數, 並且元組所佔用的內存較小。使用的話,除了沒有修改元組元素的方法外, 其餘的和列表的方法基本一致。
另外元組中的元素不能刪除,可是能夠使用del語句來刪除整個元組, 不過比較少用,由於Python回收機制會在這個元組再也不被使用時自動刪除 (和Java的gc有點像~) 還可使用**tuple(list)
**將字符串或列表轉換爲元組。
和列表,元組經過下標序列來索引元素不一樣,字典使用**鍵值對
的形式來存儲 數據,經過鍵來索引值**,建立字典時,鍵不能重複,重複後面的會覆蓋! 由於鍵必須不可變,因此鍵可用數字,字符串或元組,可是不能用列表! 使用**冒號:分割鍵與值,多個鍵值對用逗號,**分隔;字典也是支持嵌套的! 用法示例以下:
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))
複製代碼
集合中的存儲的元素無序且不重複,因此你沒法去索引某個具體的元素; 使用大括號{}包裹元素,逗號分隔,若是有重複的元素會被自動剔除! 另外有一點要注意的是,若是是建立空集合必須使用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})
複製代碼
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}{d}!".format(a = "人", c = "苦短",b = "我用",d = "Python")
print(str1) # 輸出結果:人生苦短,我用Python!
# 位置參數能夠與關鍵字參數一塊兒使用,不過位置參數須要在關鍵字參數前,不然會報錯!
# 另外還有個叫替換域的東西,冒號表明格式化符號開始,好比下面的例子:
str1 = "{0}:{1:.4}".format("圓周率", 3.1415926)
print(str1) # 輸出結果:圓周率:3.142
複製代碼
格式化操做符:%
,這個就不說了,和上面print()那裏的一致!
算術操做符:(+
-
*
/
%
**
(冪,次方) //
(地板除法,捨棄小數))
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
)
運算符優先級:
**
(指數) > ~ + -
(取反,正負號) > * / % //
(乘除,求餘,地板除) > << >>
(左右移) > &
(按位與) > ^ |
(異或,按位或) > < <= > >=
(比較運算符) > 等於運算符 > 賦值運算符 > 身份運算符 > 成員運算符 > 邏輯運算符
日期時間並不屬於數據結構,只是以爲很經常使用,索性也在這裏把用法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(秒)
複製代碼
python中沒有switch-case,另外使用了 elif
代替了else if 每一個條件後須要跟一個**冒號(:)
,經過縮放
**來劃分代碼塊, 嵌套的時候要注意!使用示例以下:
另外,若是條件成立,你又不想作任何事情,能夠直接使用**pass空語句
**
python中沒有do-while,一樣要注意冒號和縮放! 能夠搭配**else
使用,還有無限循環
這種東西:while True:
** 使用下面的**break關鍵字
能夠跳出循環
**。 使用示例以下:
和C或者Java那種for循環不一樣,並不能直接寫 for(int a = 0;a < 100;a++) 使用示例以下:
輸出結果:
break跳出循環;continue跳過餘下操做直接進入下一次循環; else也可使用在循環,for循環條件不成立時執行,若是先break的話不會執行!
a = x if 條件 else y
當**assert關鍵字
後面的判斷條件爲假的時候,程序自動崩潰並拋出AssertionErro異常**, 通常在測試程序的時候纔會用到,要確保某個條件爲真程序才能正常工做的時候使用~
迭代器
:用於訪問集合,是一種能夠記住遍歷位置的對象,會從第一個元素 開始訪問,直到結束,兩個基本的方法:iter()
和next()
輸出結果:
生成器
應該叫**生成器函數
吧,一種特別的函數,用yield
來返回值, 調用時會返回一個生成器對象
,本質上仍是迭代器,只是更加簡潔, yield對應的值在函數調用的時候不會當即返回**,只有去調用next() 方法的時候纔會返回,使用for x in xxx的時候其實調用的仍是next()方法, 最簡單的使用示例以下:
若是你用type()方法查下,會發現返回的對象類型是:<class 'generator'>
相比起迭代器,生成器更加簡潔優雅,最經典的例子就是實現斐波那契數列:
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
複製代碼
對於一些重複使用的代碼塊,咱們能夠把他抽取出來寫成一個函數。
使用 def關鍵字
修飾,後接函數名與圓括號(傳入參數), 使用 return關鍵字
返回值,不寫的話默認返回 None值
, Python能夠動態肯定函數類型,返回不一樣的類型的值,能夠利用 列表打包多種類型的值
一次性返回,也能夠直接用元組返回多個值
; 另外函數參數若是有多個的話,能夠用**逗號
隔開。 還有一個建議是:在函數第一行語句能夠選擇性地使用文檔字符串用於存放 函數說明,直接用三引號註釋**包括便可,經過help方法能夠拿到!
定義函數時的參數是形參,調用時傳入的是實參;
參數有多個的時候,怕參數混淆傳錯,能夠在傳入的時候 指定形參的參數名,好比: **show(a = "a", b = "b")**這樣。
定義的形參時候賦予默認初值,調用時就能夠不帶 參數去調用函數,好比:def sub(a = "1", b = "2"),調用時直接 什麼都傳sub()或者傳入一個參數sub(3)均可以,還能夠配合 關鍵字參數指定傳入的是哪一個參數。
有時傳入的函數參數數目多是不固定的,好比,要你 計算一組值的和,具體有多少個數字不知道,此時就能夠用可變參數了。 只須要在參數前加上***
號(實際上是把數據打包成了元組),就表明這個 參數是可變參數;若是有多個參數,寫在可變參數後的參數要用 關鍵字參數指定**,不然會加入可變參數的範疇!!!有打包天然有 解包,若是想把列表或元組當作可變參數傳入,須要在傳入的時候 在實參前加上***
號!另外,若是想把參數打包成元組的方式的話, 可使用兩個星號(**
**)修飾~
全局變量
就是定義爲在最外部的,能夠在函數內部進行訪問但不能直接修改; 局部變量
就是定義在函數內部的,而在函數外部沒法訪問的參數或變量;
局部變量沒法在外部訪問的緣由: Python在運行函數時,會利用棧(Stack)來存儲數據,執行完 函數後,全部數據會被自動刪除。
函數中沒法修改全局變量的緣由: 當試圖在函數裏修改全局變量的值時,Python會自動在函數內部新建一個 名字同樣的局部變量代替。若是硬是要修改,能夠在函數內部使用 global關鍵字
修飾全局變量,可是不建議這樣作,會使得程序 維護成本的提升。
其實就是函數嵌套,一個函數裏嵌套另外一個函數,須要注意一點: 內部函數的做用域只在內部函數的直接外部函數內,外部是 沒法調用的,若是調用會報錯的。
Python中的閉包:若是在一個外部函數中,對外部做用域(非全局)的變量 進行引用,那麼內部函數就被認爲是閉包。簡單的例子以下:
不能在外部函數之外的地方調用內部函數,會報方法名未定義。 另外,內部函數也不能直接修改外部函數裏的變量,會報UnboundLocalError錯誤! 和前面函數裏修改全局變量的狀況同樣,若是硬是要修改的話 能夠把外部函數中的變量間接經過容器類型來存放,或者使用 Python3 中提供的**nolocal關鍵字
**修飾修改的變量。例子以下:
在Python中可使用**lambda關鍵字
**來建立匿名函數,直接返回一個函數對象, 不用去糾結起什麼名字,省了定義函數的步驟,從而簡化代碼的可讀性! 簡單的對比大小lambda表達式例子以下:
big = lambda x, y: x > y
print("第一個參數比第二個參數大:%s" % big(1, 2))
# 輸出結果:第一個參數比第二個參數大:False
複製代碼
其實就是函數調用自身,最簡單的遞歸求和例子以下:
def sum(n):
if n == 1:
return 1
else:
return n + sum(n - 1)
print("1到100的求和結果是: %d" % sum(100))
# 輸出結果:1到100的求和結果是: 5050
複製代碼
語法錯誤是連編譯器那關都過不了的錯誤,好比if後漏掉:冒號,跑都跑不起來; 運行異常則是程序跑起來後,由於程序的業務邏輯問題引發的程序崩潰,好比除以0;
異常 | 描述信息 |
---|---|
AssertionError |
斷言語句失敗 |
AttributeError |
嘗試訪問未知的對象屬性 |
IndexError |
索引超出序列的範圍 |
keyError |
字典中查找一個不存在的Key |
NameError |
嘗試訪問一個不存在的變量 |
OSError |
操做系統產生的異常,好比FileNotFoundError |
SyntaxError |
Python語法錯誤 |
TypeError |
不一樣類型間的無效操做 |
ZeroDivisionError |
除數爲0 |
IOError |
輸入輸出錯誤 |
ValueError |
函數傳參類型錯誤 |
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
# 不管是否發生異常都會執行~
複製代碼
使用**raise語句
能夠直接拋出異常,好比raise TypeError(異常解釋,可選)**
當你的異常捕獲代碼僅僅是爲了保證共享資源(文件,數據等)的惟一分配, 並在任務結束後釋放掉它,那麼可使用**with語句
**,例子以下:
try:
with open('123.txt', "w") as f:
for line in f:
print(line)
except OSError as reason:
print("發生異常:" + str(reason))
# 輸出結果:發生異常:not readable
複製代碼
除了上面獲取異常信息的方式外,還能夠經過sys模塊的exc_info()
函數得到: 示例以下:
# 輸出結果依次是:異常類,類示例,跟蹤記錄對象
try:
result = 1 / 0
except:
import sys
tuple_exception = sys.exc_info()
for i in tuple_exception:
print(i)
# 輸出結果:
# <class 'ZeroDivisionError'>
# division by zero
# <traceback object at 0x7f3560c05808>
複製代碼
Python中讀寫文件很是簡單,經過**open()函數
** 能夠打開文件並 返回文件對象使用help命令能夠知道,open函數有好幾個參數:
做爲初學者,暫時瞭解前兩個參數就夠了: file參數:文件名,不帶路徑的話會在當前文件夾中查找; mode:打開模式,有如下幾種打開方式:
模式 | 做用 |
---|---|
r |
只讀模式打開,默認 |
w |
寫模式打開,若文件存在,先刪除,而後從新建立 |
a |
追加模式打開,追加到文件末尾,seek()指向其餘地方也沒用,文件不存在,自動建立 |
b |
二進制模式打開 |
t |
文本模式打開,默認 |
+ |
可讀寫模式,可配合其餘模式使用,好比r+,w+ |
x |
若是文件已存在,用此模式打開會引起異常 |
U |
通用換行符支持 |
函數 | 做用 |
---|---|
close() | 關閉文件,關閉後文件不能再進行讀寫操做 |
read(size=-1) | 從文件讀取指定的字節數,若是未設置或爲負數,讀取全部 |
next() | 返回文件下一行 |
readline() | 讀取整行,包括換行符'\n' |
seek(offset, from) | 設置當前文件指針的位置,從from(0文件起始位置,1當前位置, 2文件末尾)偏移offset個字節 |
tell() | 返回文件的當前位置 |
write(str) | 將字符串寫入文件 |
writelines(seq) | 寫入一個序列字符串列表,若是要換行,須要本身加入每行的換行符 |
# 讀取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
複製代碼
輸出結果:
須要導入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) | 判斷兩個路徑是否指向同一個文件 |
PS:Python中沒有像其餘語言同樣有public或者private的關鍵字 來區分公有仍是私有,默認公有,若是你想定義私有屬性或者函數, 命名的時候在前面加上兩下劃線__
便可,實際上是僞私有,內部 採用的是名字改編技術,改爲了**_類名__私有屬性/方法名
,好比 下面調用people._Person__skill**,是能夠訪問到私有成員的! 類中的屬性是靜態變量。
輸出結果:
__init__(self)
構造方法實例化對象的時候會自動調用,當你想傳參的時候能夠用它~
輸出結果:
規則以下:
class 子類(父類):
super()函數.
** 方法名調用;Python支持多繼承,多個父類用逗號隔開,子類可同時繼承多個父類的 屬性與方法多繼承的時候若是父類們中有相同的方法,調用的順序是 誰在前面先調用那個父類中的方法,好比有class Person(Name, Sex,Age), 三個父類裏都有一個show的方法,那麼子類調用的是Name裏的show()! 若是不是得用多繼承不可的話,應該儘可能避免使用它,有時會出現 一些不可碰見的BUG。
還有一種叫組合的套路,就是在把須要用到的類丟到組合類中 實例化,而後使用,好比把Book,Phone,Wallet放到Bag裏:
輸出結果:
函數 | 做用 |
---|---|
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) | 返回一個能夠設置屬性的屬性 |
保存爲**.py後綴的文件都是一個獨立的模塊,好比有a.py和b.py文件, 你能夠在a中import b,而後就可使用b.py中的函數了。 模塊導入規則4.1 導包**處就寫得詳細了,此處就不重複描述了。
導入其餘模塊的時候,測試部分的代碼也會執行,能夠經過 __name__
告訴Python該模塊是做爲程序運行仍是導入到其餘程序中。 做爲程序運行時該屬性的值是__main__
,只有單獨運行的時候纔會執行。 好比:
if __name__ == '__main__':
test()
複製代碼
Python模塊的導入會有一個路徑搜索的過程,若是這些搜索路徑都找不到的話, 會報ImportError,能夠經過打印sys.path能夠看到這些搜索路徑,好比個人:
若是你的模塊都不在這些路徑裏,就會報錯,固然也能夠經過 sys.path.append("路徑")
把路徑添加到搜索路徑中!
方法一: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 # 查看已安裝庫列表
複製代碼
當你開始學爬蟲,電腦會慢慢多不少妹子圖,別問我爲何... 一些小夥伴看到會問你拿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的基礎知識過了一遍,固然確定是會有遺漏的 後面想到再補上吧,擼基本知識是挺乏味的,期待後續爬蟲學習~
來啊,Py交易啊
想加羣一塊兒學習Py的能夠加下,智障機器人小Pig,驗證信息裏包含: Python,python,py,Py,加羣,交易,屁眼 中的一個關鍵詞便可經過;
驗證經過後回覆 加羣 便可得到加羣連接(不要把機器人玩壞了!!!)~~~ 歡迎各類像我同樣的Py初學者,Py大神加入,一塊兒愉快地交流學♂習,van♂轉py。