1. 程式人生 > 實用技巧 >直接讓web服務執行在80端不行嗎,為什麼要用nginx反向代理?

直接讓web服務執行在80端不行嗎,為什麼要用nginx反向代理?

python基本知識

python儲存資料的方法 :先在記憶體中儲存資料後,再用標籤引入

python對大小寫敏感

python中通過縮排來控制結構層次

檢視某功能的使用方法: help(名稱)

載入庫的語句是: import + 庫的名字

呼叫庫中某功能的語句: 庫名.功能

ctrl+/ 註釋多行

解釋用法 ———> 雙擊:Ctrl加q

Python3 中有六個標準的資料型別:

Number(數字):	int、float、bool、complex(複數)
String(字串)
List(列表)
Tuple(元組)
Set(集合)
Dictionary(字典)

不可變資料(3 個):Number(數字)、String(字串)、Tuple(元組)

可變資料(3 個):List(列表)、Dictionary(字典)、Set(集合)

資料型別轉化:
frozenset(s)	轉換為不可變集合
chr(x)	將一個ascll轉換為一個字元
ord(x)	將一個字元轉換為它的ascll值
hex(x)	將一個整數轉換為一個十六進位制字串
oct(x)	將一個整數轉換為一個八進位制字串
set(s)	轉換為可變集合

交換a b的值 a,b=b,a

輸入語法:input() 函式接受一個標準輸入資料,返回為 string 型別。

輸入格式的控制 a,b,c=input().split(' ') 輸入a,b,c時 將a,b,c用空格隔開

split 返回型別為 列表型

輸出格式的控制 print("{:.2f}{:.2f}{:.2f}".format(a,b,c)) 輸出a b c時控制格式為 a_b_c 且保留兩位小數 花括號代表輸出的數,在花括號裡設定輸出格式

排序內建函式 sorted()

生成等差數列 格式range(,,_)---(起始,結束,步長) 注: x=range(1,100)取不到100,99為邊界

map的型別轉換:

若輸入 23 45 56
x=input().split(' ')
y1=list(x)
y2=list(map(int,y1)) #y1中的元素型別為整型,再放在列表y2中
print(y1) 結果為 ['23', '45', '56']
print(y2) 結果為 [23, 45, 56]

eval 型別隨意轉換 作用:將字元型別轉換為其他型別
a='[5645]' b=eval(a) print(type(b)) 將字串轉換為列表型別
a='2.3' b=eval(b) 將字串轉換float型別

獲取資料型別 type()

判斷型別isinstance (x,int) x是否為int型

獲取地址 id()

處理序列的方法: (序列型別:字串、元祖、列表)
通用操作符:
s + t 表示連線 s t 兩個序列
s*n 表示s序列重複n次
in 判斷元素是否在序列中。若是返回True 否則返回False
s[i] 索引,返回s中的第i個元素,i是序列的序號,正下標正向找,負下標逆向找
s[i:j:k] 切片,返回序列s中第i到j以k為步長的元素子序列 倒序y=x[::-1] 注:切片時必須在最後字元後再加1,因為python只會擷取到最後字元的前一個字元。
函式和方法:
len(s) 返回序列s長度
min(s) 返回序列s的最小元素
max(s) 返回序列s的最大元素
s.index(x,i,j) 返回序列s從i開始到j位置中第一次出現元素x的位置
s.count(x) 返回序列s中出現x的總次數
b.join(a) 方法用於將序列a中的元素以指定的字元b連線生成一個新的字串 a='49685' b='+' c=b.join(a) 結果4+9+6+8+5

列表 list 格式 [] (列表的資料項不需要具有相同的型別) 可變型別 ——>更改後其 id 仍然不變

操作方法:
1 ls[i] = x
替換列表ls第i元素為x
2 cmp(list1, list2)
比較兩個列表的元素,相同返回 0 ;a>b返回正值;a<b返回負值
3 len(list)
列表元素個數
4 max(list)
返回列表元素最大值
5 min(list)
返回列表元素最小值
6 list(seq)
將元組轉換為列表

函式方法:

1 list.append(obj)或list1 + list2
在列表末尾新增新的物件
2 list.count(obj)
統計某個元素在列表中出現的次數
3 list.extend(seq)
在列表末尾一次性追加另一個序列中的多個值(用新列表擴充套件原來的列表)
4 list.index(obj)
從列表中找出某個值第一個匹配項的索引位置
5 list.insert(index, obj)
將物件插入列表
6 list.pop(i)
移除列表中的第i元素,並且返回該元素的值
7 list.remove(x)
移除列表中出現的第一個元素x
8 list.reverse()
將列表中的元素反轉
9 list.sort(cmp=None, key=None, reverse=False)
對原列表進行排序
10 list.insert(i,x)
在列表的第i位置增加元素x
11 list.copy()
複製列表的內容

注:x=[12,"bc12"]
y=x.copy() <——> y=x 兩者意義不同

元組 tuple 格式 () 只能讀不能寫的列表

注: 定義只有一個元素的原組時,要在一個原素後加逗號————>>>a=(3,) 而不是a=(3)

定義空原組 格式a=()

字典 dict 格式 { : } 鍵/值對

集合 set 格式 {} 不能有重複元素,只讀不寫,無序結構

注: 列表 原組 字典 集合 中的元素可以是任意型別

format用法
1.作為拼接字串進行使用

  '{}'.format(變數)     例 x='123'  z='456'   print("{}{}".format(x,z))  結果為 123456
  1. 保留小數
'{:.2f}'.format(12.333)        保留小數點後兩位

'{a:.2f}'.format(a=12.333)

3.百分比格式

'{:.2%}'.format(0.333)    

物件 = 屬性+方法

算術運算子 / * - + % ** (冪次) // (返回商的整數部分,(向下取整))
關係運算符 > < >= <= != == is is not in not in
邏輯運算子 and or not
布林型別 true false

選擇結構
if_____:

  elif_____:  或   else  :

迴圈結構
for 取值 in 序列或迭代物件 : #一般用於迴圈次數可知

while_____: #一般用於迴圈次數未知
_____

def定義的函式 注:輸出最好不要放在函式中
格式:
def 函式名(形參列表):
"函式_文件字串"
function_suite
return [expression]
規則:
函式程式碼塊以 def 關鍵詞開頭,後接函式識別符號名稱和圓括號()。
任何傳入引數和自變數必須放在圓括號中間。圓括號之間可以用於定義引數。
return [表示式] 結束函式,選擇性地返回一個值給呼叫方。不帶表示式的return相當於返回 None。
(return 可以有多個返回值)

lambda函式
格式 lambda 引數 : 引數的運算式
例:
f=lambda x,y : x+y
type(f)
f(12,34) #計算兩數之和,輸出:46

注:定義函式時存在預設值:
eg def dup(str,times=2) #times=2即為預設值
print(str*times)
print(dup("yes"))
print(dup("yes",4))

可變引數
格式: y 例(x,y) 呼叫函式時,剩下的引數都被收集為一個元組
def hy(x, *y):
print(x, y)
a,b,c,d=input().split(' ')
hy(a,b,c,d)
輸出結果為 12 ('23', '56', '48')

格式:y eg (x,y)呼叫函式時,剩下的引數都被收集為一個字典
def hy(a,b,*c,**d):
total=a+b
for n in c:
total=total+n
for key in d:
total=total+d[key]
return total
print(hy(1,2))#計算1+2
print(hy(1,2.3,4,5))#計算1+2+3+4+5

全域性變數 (global) 全域性變數是在函式外部定義和宣告的變數
注:如果在函式範圍內定義了具有相同名稱的變數,那麼它將僅列印函式內給出的值而不是全域性值。
區域性變數 區域性變數是指在函式內部定義並使用的變數,它只在函式內部有效

檔案: (檔案的寫入:開啟、寫入、關閉)
開啟:
格式 open(file, mode, buffering, encoding)
file 檔案路徑(相對或者絕對路徑)
mode 檔案開啟模式
'r' 只讀
'w' 寫入,寫入前刪除舊內容
'x' 建立新檔案
'a' 追加
'b' 二進位制檔案
't' 文字檔案,預設值
'+' 更新,讀寫
寫入:
f.write()
try:
with open('E:\pachong\data1.txt','w') as f:#檔案寫入到指定路徑文字
f.write('houyi')
f1=open('E:\pachong\data1.txt','r') #讀取指定路徑的文字內容
s=f1.read()
print(s)
f.close() #關閉檔案
except:
print('error')
注意 :readline/readlines 讀取行資料 writelines() 寫行資料

處理異常:
try 語句可以在執行時系統地處理異常和錯誤
格式 try:

except:
pass #空語句

python庫的安裝:

庫的安裝方法: pip install 庫名 -i https://pypi.tuna.tsinghua.edu.cn/simple
解除安裝 : pip uninstall 庫名

爬 蟲

python的爬去思路:

  1. 瞭解網頁;
    2.抓取網站資料;
    3.解析網頁
    4.清洗和組織資料;
    5.爬蟲攻防戰;

常見編碼方式:Unicode ASCII UTF-8

認識網頁結構
網頁一般由三部分組成,分別是 HTML(超文字標記語言)、CSS(層疊樣式表)和 JScript(活動指令碼語言)。
(如果用人體來比喻,HTML 是人的骨架,並且定義了人的嘴巴、眼睛、耳朵等要長在哪裡。CSS 是人的外觀細節,如嘴巴長什麼樣子,
眼睛是雙眼皮還是單眼皮,是大眼睛還是小眼睛,面板是黑色的還是白色的等。JScript 表示人的技能,例如跳舞、唱歌或者演奏樂器等。)

網頁請求的過程分為兩個環節:

Request (請求):每一個展示在使用者面前的網頁都必須經過這一步,也就是向伺服器傳送訪問請求。
Response(響應):伺服器在接收到使用者的請求後,會驗證請求的有效性,然後向用戶(客戶端)傳送響應的內容,客戶端接收伺服器響應的內容,將內容展示出來

注意:python中class是關鍵字,為了防止衝突,這裡使用class_表示標籤的class屬性

Requests庫的7個請求方法(method):
requests.request('method大寫','url',**kwargs) 構造一個請求,支撐以下各方法的基礎方法
**kwargs:控制訪問的引數,均為可選項(13個)
params:字典或位元組序列作為引數增加到url中
data:字典、位元組序列或檔案物件,作為Request的內容
json:JSON格式的資料,作為Request的內容
headers;字典,HTTP定製頭
cookies:字典或CookieJar,Request中的cookie
auth:元組,支援HTTP認證功能
files:字典型別,傳輸檔案
timeout:設定超時時間,秒為單位
proxies:字典型別,設定訪問代理伺服器,可以增加登入認證
allow_redirects:True/False,預設為True,重定向開關
stream:True/False,預設為True,獲取內容立即下載開關
verify:True/False,預設為True,認證SSL證書開關
cert:本地SSL證書路徑
requests.get() 獲取HTML網頁的主要方法,對應於HTTP的GET
requests.head() 獲取HTML網頁頭資訊的方法,對應HTTP的HEAD方法 r.headers
requests.post() 向HTML網頁提交POST請求的方法,對應HTTP的POST方法, r.requests.post(url)
requests.put() 向HTML網頁提交PUT請求的方法,對應HTTP的PUT方法 r.requests.put(url)
requests.patch() 向HTML網頁提交區域性修改請求,對應HTTP的PATCH方法
requests.delete() 向HTML頁面提交刪除請求,對應HTTP的DELETE方法

response物件的屬性 : (r=requests.get() --> r為response物件)
r.status_code HTTP請求的返回狀態,200表示連線成功,404表示失敗
r.text HTTP響應內容的字串形式,即url對應的頁面內容
r.encoding 從HTTP header中猜測的響應內容編碼方式,如果header中不存在charset,則認為編碼為IOS-8859-1
r.apparent_encoding 從內容中分析出的響應內容編碼方式(備選編碼方式)
r.content HTTP響應內容的二進位制形式

理解Requests庫的異常
requests.ConnectionError 網路連線錯誤異常,如DNS查詢失敗、拒絕連線等
requests.HTTPError HTTP錯誤異常
requests.URLRequired URL缺失異常
requests.TooManyRedirects 超過最大重定向次數,產生重定向異常
requests.ConnectTimeout 連線遠端伺服器超時異常
requests.Timeout 請求URL超時異常(全過程異常)
r.raise_for_status() 如果不是200,產生異常requests.HTTPError

爬取網頁的通用程式碼框架
import requests
try:
kv={user-agent:Mozilla/5.0}
r=requests.get(url,timeout=30,headers=kv)
r.raise_for_status() #如果狀態不是200,引發HTTPError異常
r.encoding=r.apparent_encoding
print(r.text)
except:
print("產生異常")

html結構基礎:
標籤 > 屬性=鍵+值
<! 表示註釋的開始

來源審查:判斷User-Agent進行限制,
釋出公告:Robots協議 網站根目錄下的robots.txt

BeautifulSoup類 = html = 標籤樹

BeautifulSoup類的基本元素:
Tag 標籤
Name 標籤的名字 格式 .name
Attributes 標籤的屬性,字典形式組織 格式 .attrs
NavigableString 標籤內非屬性字串 格式 .string
Comment 標籤內字串的註釋部分 <! 表示註釋的開始

BeautifulSoup庫的用法:
from bs4 import BeautifulSoup
soup=BeautifulSoup('__','直譯器')

解析器:(4種)
html.parser
lxml
xml
html5lib

標籤樹的三種遍歷方式:
下行遍歷:
.contents 子節點的列表,將所有兒子節點存入列表
.children 子節點的迭代型別,與.contents類似,用於迴圈遍歷兒子節點
.descendants 子孫節點的迭代型別,包含所有子孫節點,用於迴圈遍歷
迭代型別:
for child in soup.body.children: 遍歷兒子節點
print(child)
for child in soup.body.children: 遍歷子孫節點
print(child)
上行遍歷:
.parent 節點的父親標籤
.parents 節點先輩標籤的迭代型別,用於迴圈遍歷先輩節點
迭代型別:
for parent in soup.a.parents:
if parent is None: #注意在遍歷某標籤的先輩節點時會遍歷到soup本身,而soup的先輩不存在.name
print(parent)
else:
print(parent.name)

平行遍歷:(平行遍歷發生在同一個父節點下的各節點間)
.next_sibling 返回按照HTML文字順序的下一個平行節點標籤
.previous_sibling 返回按照HTML文字順序的上一個平行節點標籤
.next_siblings 迭代型別,返回照HTML文字順序的後續所有平行節點標籤
.previous_siblings 迭代型別,返回照HTML文字順序的前續所有平行節點標籤

迭代型別:
for sibling in soup.a.next_siblings:
print(sibling)
for sibling in soup.a.previous_siblings:
print(sibling)

基於bs4庫的HTML格式輸出:(讓html的內容更友好)
soup.prettify()

資訊標記=標記+資訊:(更利於理解)
XML 通過標籤形式構建所有資訊 <>.....<>
JSON 有型別的鍵值對: key:value 對給出的資訊做一個型別的定義 "name":"北京" 注意:鍵和值若為字串形式要加""
YAML 無型別鍵值對 : key:value name:北京 通過縮排表達所屬關係,- 表示並列關係,| 表達整塊資料, # 表達註釋
三種標記的比較:
XML Internet上資訊的互動與傳遞
JSON 移動應用雲端和節點的資訊通訊,無註釋
YAML 各類系統的配置檔案,有註釋易讀

資訊提取的一般方式:
1、需要標記解析器
2、無視標記形式,直接搜尋關鍵資訊
3、1+2

BeautifulSoup庫的 find_all
作用:返回一個列表型別,儲存查詢的結果
格式:find_all(name,attrs,recursive,string,**kwargs)
recursive:是否對子孫全部檢索,預設為True
(...) 等價於 .find_all(...)
soup(...) 等價於 soup.find_all(...)
find_all的擴充套件方法:
<>.find()搜尋,返回一個結果,字串型別,
<>.find_parents()在先輩節點中搜索,返回列表型別
<>.find_parent()在先輩節點中返回一個結果,字串型別
<>.find_next_siblings()在後續平行節點中搜索,返回列表型別
<>.find_next_sibling()在後續平行節點中返回一個結果,字串型別
<>.find_previous_siblings()在前序節點中搜索,返回列表型別
<>.find_previous_sibling()在前序節點中返回一個結果,字串型別

正則表示式:
正則表示式(通過re模組實現)
import re # 引入re
正則表示式的表達型別:
raw string型別(原生字串型別) 格式 r'__'
string型別更繁瑣
注:在帶有 'r' 字首的字串字面值中,反斜槓不必做任何特殊處理。

pattern (原生字串)
string (待匹配字串)
flags (標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等)
re.I 使不區分大小寫
re.M ^將給定字串的每行當作匹配的開始
re.S . 預設匹配除換行外的的所有字元
maxsplit 最大分割數,剩餘部分作為最後一個元素輸出
repl 替換匹配字串的字串
count 替換次數

正則表示式的匹配實現:
1、 先將正則表示式的字串形式編譯為pattern例項
格式 r'__' 或 re.compile(pattern,flags=0)
注: compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件

2、 使用pattern例項處理文字並獲得匹配結果
3、 使用例項獲得資訊,進行其他操作

Re庫主要功能函式:
re.search(pattern,string,flags=0) 在一個字串中搜索匹配和正則表示式一樣的地方,返回match物件
re.match(pattern,string,flags=0) 從一個字串的開始位置起匹配正則表示式,返回match物件
re.findall(pattern,string,flags=0) 搜尋字串,以列表型別返回全部能匹配的子串
re.split(pattern,string,maxsplit,flags=0) 將一個字串按照正則表示式匹配結果進行分割,返回列表型別
re.finditer(pattern,string,flags=0) 搜尋字串,返回一個匹配結果的迭代型別,每個迭代元素是match物件
re.sub(pattern,repl,string,count=0,flags=0) 在一個字串中替換所有匹配正則表示式的子串,返回替換後的字串

Match物件的屬性
.string 待匹配的文字
.re 匹配時使用的pattern物件(正則表示式)
.pos 正則表示式搜尋文字的開始位置
.endpos 正則表示式搜尋文字結束位置

Match物件的方法
.group(0) 獲得匹配後的字串
.start 匹配字串在原始字串的開始位置
.end 匹配字串在原始字串的結束位置
.span() 返回(.start(),.end())

元字元
. 表示任何單個字元
[] 字符集 [abc]表示a、b、c [a-z]表示a到z單個字元
[^] 非字符集,對單個字元給出排除範圍 [^abc]表示非a或b或c的單個字元
^ 匹配行首 ^123表示123存在且在一個字串的開頭
$ 匹配行尾 123$表示123存在且在一個字串的結尾

  • 前的一個字元可被匹配零次或多次 eg: ab2 將ab重複2次
  • +前的一個字元至少被匹配1次 eg: ab+
    ? ?前的一個字元被匹配0次或1次 eg: ab?表示a或ab
    {m,n} 匹配{}前一個字元最小重複m次,最多重複n次
    \ 轉義字元
    | 左右表示式任意一個 abc|def 表示 abc、def
    () 分組標記,內部只能使用|操作符 (abc)表示abc, (abc|def)表示abc、def
    \d 數字,等價於[0-9]
    \w 單詞字元,等價於[A-Za-z0-9_]

經典正則表示式例項:
[1]+$ 由26個字母組成的字串
[2]+$ 由26個字母和數字組成的字串
^-?\d+$ 整數形式的字串
[3][1-9][0-9]$ 正整數形式的字串
[1-9]\d{5} 中國境內郵政編碼,6位
[\u4e00-\u9fa5] 匹配中文字元
\d{3}-\d{8}|\d{4}-\d{7} 國內電話號碼,

貪婪匹配
Re庫預設採用貪婪匹配,即輸出匹配最長的子串
例 match=re.search(r.'PY.*N','PYANBNCNDN') print(match.group(0))結果為PYANBNCNDN
最小匹配
*? 前一個字元被匹配0次或多次
+? 前一個字元被匹配1次或多次
?? 前一個字元被匹配0次或1次
{m,n}? 匹配前一個字元m次至n次

python對記憶體的使用
b=a使得 a 和 b 指向同一個地址區間,改變a的同時,b的值也會改變,(若使a改變但b不變則用拷貝的方法)
深拷貝 格式 import copy c=copy.a a和c指向不同的地址區間,改變a,c的值不變
淺拷貝

注:if name == 'main'的意思是:當.py檔案被直接執行時,if name == 'main'之下的程式碼塊將被執行;當.py檔案以模組形式被匯入時,if name == 'main'之下的程式碼塊不被執行。

Python中的類 class:

類通過 class 關鍵字定義,類名通用習慣為首字母大寫,Python3中類基本都會繼承於object類

建立一個Circle圓類:
格式:
class Circle(object): # 建立Circle類,Circle為類名
pass # 此處可新增屬性和方法
注意:我們定義的類都會繼承於object類

建立例項:
有了Circl創建出具體的circle1、circle2等例項,circle1和circle2是個實際的圓。建立例項使用 類名+(),類似函式呼叫的形式建立。
格式:
circle1= Circle()
circle2= Circle()

例項屬性:用於區分不同的例項
類屬性:每個例項的共有屬性
注:例項屬性每個例項都各自擁有,相互獨立;而類屬性有且只有一份,是共有的屬性。

init() 方法:
在定義 Circle 類時,可以為 Circle 類新增一個特殊的 init() 方法,當建立例項時,init() 方法被自動呼叫為建立的例項增加例項屬性。
我們在此為每個例項都統一加上我們需要的屬性:

class Circle(object): # 建立Circle類
def init(self, r): # 初始化一個屬性r(不要忘記self引數,他是類下面所有方法必須的引數)
self.r = r #表示給我們將要建立的例項賦予屬性r賦值

表示給我們將要建立的例項賦予屬性r賦值

注意:init() 方法的第一個引數必須是 self(self代表類的例項,可以用別的名字,但建議使用約定成俗的self),後續引數則可以自由指定,和定義函式沒有任何區別。

建立例項時就必須要提供除 self 以外的引數:

circle1 = Circle(1) # 建立例項時直接給定例項屬性,self不算在內
circle2 = Circle(2)
print(circle1.r) # 例項名.屬性名 訪問屬性
print(circle2.r) # 我們呼叫例項屬性的名稱就統一了

定義類方法:
在類的內部,使用 def 關鍵字來定義方法,與一般函式定義不同,類方法必須第一個引數為 self, self 代表的是類的例項(即你還未建立類的例項),其他引數和普通函式是完全一樣。

如下我們給圓類 Circle 新增求面積的方法 get_area
class Circle(object):
pi = 3.14 # 類屬性

def init(self, r):
self.r = r # 例項屬性

def get_area(self):# 定義類方法
""" 圓的面積 """
# return self.r2 * Circle.pi # 通過例項修改pi的值對面積無影響,這個pi為類屬性的值
return self.r
2 * self.pi # 通過例項修改pi的值對面積我們圓的面積就會改變

circle1 = Circle(1)
print(circle1.get_area()) # 呼叫方法 self不需要傳入引數,不要忘記方法後的括號 輸出 3.14
注:示例中的 get_area(self) 就是一個方法,它的第一個引數是 self

Queue:主要用於多生產者和消費者模式下的佇列實現,特別適合多執行緒時的訊息交換

queue模組實現了三種佇列:
FIFO:先進先出佇列,類似管道。元素只能從隊頭方向一個一個的彈出,只能從隊尾一個一個的放入。

LIFO:後進先出佇列,也就是棧。元素永遠只能在棧頂出入。

priority queue:優先順序佇列,每個元素都帶有一個優先值,值越小的越早出去。值相同的,先進入佇列的先出去。

queue模組定義了下面幾個類和異常(一定要注意大小寫!) :
class queue.Queue(maxsize=0):
FIFO佇列構造器。maxsize是佇列裡最多能同時存在的元素個數。如果佇列滿了,則會暫時阻塞佇列,直到有消費者取走元素。maxsize的值如果小於或等於零,表示佇列元素個數不設上限,理論上可無窮個,但要小心,記憶體不是無限大的,這樣可能會讓你的記憶體溢位。
class queue.LifoQueue(maxsize=0)
LIFO佇列構造器。maxsize是佇列裡最多能同時放置的元素個數。如果佇列滿了,則會暫時阻塞佇列,直到有消費者取走元素。maxsize的值如果小於或等於零,表示佇列元素個數不設上限,可無窮個。
class queue.PriorityQueue(maxsize=0)
優先順序佇列構造器。maxsize是佇列裡最多能同時放置的元素個數。如果佇列滿了,則會暫時阻塞佇列,直到有消費者取走元素。maxsize的值如果小於或等於零,表示佇列元素個數不設上限,可無窮個。通常在這類佇列中,元素的優先順序是按sorted(list(entries))[0]的結果來定義的,而元素的結構形式通常是(priority_number, data)型別的元組。
exception queue.Empty
從空的佇列裡請求元素的時候,彈出該異常。
exception queue.Full
往滿的佇列裡放入元素的時候,彈出該異常。
Queue物件:
三種佇列類的物件都提供了以下通用的方法:

Queue.qsize()

返回當前佇列內的元素的個數。注意,qsize()大於零不等於下一個get()方法一定不會被阻塞,qsize()小於maxsize也不表示下一個put()方法一定不會被阻塞。

Queue.empty()

佇列為空則返回True,否則返回False。同樣地,返回True不表示下一個put()方法一定不會被阻塞。返回False不表示下一個get()一定不會被阻塞。

Queue.full()

與empty()方法正好相反。同樣不保證下一步的操作不被阻塞。

Queue.put(item, block=True, timeout=None)

item引數表示具體要放入佇列的元素。block和timeout兩個引數配合使用。其中,如果block=True,timeout=None,佇列阻塞,直到有空槽出現;當block=True,timeout=正整數N,如果在等待了N秒後,佇列還沒有空槽,則彈出Full異常;如果block=False,則timeout引數被忽略,佇列有空槽則立即放入,如果沒空槽,則彈出Full異常。

Queue.put_nowait(item)

等同於put(item, False)

Queue.get(block=True, timeout=None)

從佇列內刪除並返回一個元素。如果block=True, timeout=None,佇列會阻塞,直到有可供彈出的元素。如果timeout指定為一個正整數N,則在N秒內如果佇列內沒有可供彈出的元素,則丟擲Empty異常。如果block=False,timeout引數會被忽略,此時佇列內如果有元素則直接彈出,無元素可彈,則丟擲Empty異常。

Queue.get_nowait()

等同於get(False).

下面的兩個方法用於跟蹤排隊的任務是否被消費者守護執行緒完全處理。

Queue.task_done()

表明先前的佇列任務已完成。由消費者執行緒使用。

Queue.join()

阻塞佇列,直到佇列內的所有元素被獲取和處理。

當有元素進入佇列時未完成任務的計數將增加。每當有消費者執行緒呼叫task_done()方法表示一個任務被完成時,未完成任務的計數將減少。當該計數變成0的時候,join()方法將不再阻塞。

多執行緒程式設計:

threading庫:
方法與屬性 描述
current_thread() 返回當前執行緒
active_count() 返回當前活躍的執行緒數,1個主執行緒+n個子執行緒
get_ident() 返回當前執行緒
enumerater() 返回當前活動 Thread 物件列表
main_thread() 返回主 Thread 物件
settrace(func) 為所有執行緒設定一個 trace 函式
setprofile(func) 為所有執行緒設定一個 profile 函式
stack_size([size]) 返回新建立執行緒棧大小;或為後續建立的執行緒設定棧大小為 size
TIMEOUT_MAX Lock.acquire(),RLock.acquire(),Condition.wait()允許的最大超時時間

threading模組包含下面的類:
• Thread:基本執行緒類
o threading.Thread(self, group=None, target=None, name=None,args=(), kwargs=None, *, daemon=None)
 引數group是預留的,用於將來擴充套件;
 引數target是一個可呼叫物件,線上程啟動後執行;
 引數name是執行緒的名字。預設值為“Thread-N“,N是一個數字。
 引數args和kwargs分別表示呼叫target時的引數列表和關鍵字引數

o Thread類定義了以下常用方法與屬性:
方法與屬性 說明
start() 啟動執行緒,等待CPU排程
run() 執行緒被cpu排程後自動執行的方法
getName()、setName()和name 用於獲取和設定執行緒的名稱。
setDaemon() 設定為後臺執行緒或前臺執行緒(預設是False,前臺執行緒)。如果是後臺執行緒,主執行緒執行過程中,後臺執行緒也在進行,主執行緒執行完畢後,後臺執行緒不論成功與否,均停止。如果是前臺執行緒,主執行緒執行過程中,前臺執行緒也在進行,主執行緒執行完畢後,等待前臺執行緒執行完成後,程式才停止。
ident 獲取執行緒的識別符號。執行緒識別符號是一個非零整數,只有在呼叫了start()方法之後該屬性才有效,否則它只返回None。
is_alive() 判斷執行緒是否是啟用的(alive)。從呼叫start()方法啟動執行緒,到run()方法執行完畢或遇到未處理異常而中斷這段時間內,執行緒是啟用的。
isDaemon()方法和daemon屬性 是否為守護執行緒
join([timeout]) 呼叫該方法將會使主調執行緒堵塞,直到被呼叫執行緒執行結束或超時。引數timeout是一個數值型別,表示超時時間,如果未提供該引數,那麼主調執行緒將一直堵塞到被調執行緒結束。
o
• Lock:互斥鎖
• RLock:可重入鎖,使單一程序再次獲得已持有的鎖(遞迴鎖)
• Condition:條件鎖,使得一個執行緒等待另一個執行緒滿足特定條件,比如改變狀態或某個值。
• Semaphore:訊號鎖。為執行緒間共享的有限資源提供一個”計數器”,如果沒有可用資源則會被阻塞。
• Event:事件鎖,任意數量的執行緒等待某個事件的發生,在該事件發生後所有執行緒被啟用
• Timer:一種計時器
• Barrier:Python3.2新增的“阻礙”類,必須達到指定數量的執行緒後才可以繼續執行。
建立多執行緒:
繼承Thread類,並重寫它的run()方法:
import threading

class MyThread(threading.Thread):
def init(self, thread_name):
# 注意:一定要顯式的呼叫父類的初始化函式。
super(MyThread, self).init(name=thread_name)

def run(self):
    print("%s正在執行中......" % self.name)

if name == 'main':
for i in range(10):
MyThread("thread-" + str(i)).start()

在例項化threading.Thread物件的時候,將執行緒要執行的任務函式作為引數傳入執行緒
import threading

import time

def show(arg):
time.sleep(1)
print('thread '+str(arg)+" running....")

if name == 'main':
for i in range(10):
t = threading.Thread(target=show, args=(i,))
t.start()

網路程式設計:socket庫,socket又稱“套接字”

socket型別 描述
socket.AF_UNIX 只能夠用於單一的Unix系統程序間通訊
socket.AF_INET IPv4
socket.AF_INET6 IPv6
socket.SOCK_STREAM 流式socket , for TCP
socket.SOCK_DGRAM 資料報式socket , for UDP
socket.SOCK_RAW 原始套接字,普通的套接字無法處理ICMP、IGMP等網路報文,而SOCK_RAW可以;其次,SOCK_RAW也可以處理特殊的IPv4報文;此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由使用者構造IP頭。
socket.SOCK_SEQPACKET 可靠的連續資料包服務
建立TCP Socket: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
建立UDP Socket: s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

socket是基於C/S架構的,也就是說進行socket網路程式設計,通常需要編寫兩個py檔案,一個服務端,一個客戶端。

Python中的socket通訊邏輯如下

建立套接字:
sk = socket.socket([family[, type[, proto]]])
引數說明:
family: 套接字家族,可以使AF_UNIX或者AF_INET。
type: 套接字型別,根據是面向連線的還是非連線分為SOCK_STREAM或SOCK_DGRAM,也就是TCP和UDP的區別。
protocol: 一般不填預設為0。
直接socket.socket(),則全部使用預設值。
套接字的用法:

方法 描述
伺服器端方法
s.bind() 繫結地址(host,port)到套接字,在AF_INET下,以元組(host,port)的形式表示地址。
s.listen(backlog) 開始監聽。backlog指定在拒絕連線之前,作業系統可以掛起的最大連線數量。該值至少為1,大部分應用程式設為5就可以了。
s.accept() 被動接受客戶端連線,(阻塞式)等待連線的到來,並返回(conn,address)二元元組,其中conn是一個通訊物件,可以用來接收和傳送資料。address是連線客戶端的地址。
客戶端方法
s.connect(address) 客戶端向服務端發起連線。一般address的格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤。
s.connect_ex() connect()函式的擴充套件版本,出錯時返回出錯碼,而不是丟擲異常
公共方法
s.recv(bufsize) 接收資料,資料以bytes型別返回,bufsize指定要接收的最大資料量。
s.send() 傳送資料。返回值是要傳送的位元組數量。
s.sendall() 完整發送資料。將資料傳送到連線的套接字,但在返回之前會嘗試傳送所有資料。成功返回None,失敗則丟擲異常。
s.recvform() 接收UDP資料,與recv()類似,但返回值是(data,address)。其中data是包含接收的資料,address是傳送資料的套接字地址。
s.sendto(data,address) 傳送UDP資料,將資料data傳送到套接字,address是形式為(ipaddr,port)的元組,指定遠端地址。返回值是傳送的位元組數。
s.close() 關閉套接字,必須執行。
s.getpeername() 返回連線套接字的遠端地址。返回值通常是元組(ipaddr,port)。
s.getsockname() 返回套接字自己的地址。通常是一個元組(ipaddr,port)
s.setsockopt(level,optname,value) 設定給定套接字選項的值。
s.getsockopt(level,optname[.buflen]) 返回套接字選項的值。
s.settimeout(timeout) 設定套接字操作的超時期,timeout是一個浮點數,單位是秒。值為None表示沒有超時期。一般,超時期應該在剛建立套接字時設定,因為它們可能用於連線的操作(如connect())
s.gettimeout() 返回當前超時期的值,單位是秒,如果沒有設定超時期,則返回None。
s.fileno() 返回套接字的檔案描述符。
s.setblocking(flag) 如果flag為0,則將套接字設為非阻塞模式,否則將套接字設為阻塞模式(預設值)。非阻塞模式下,如果呼叫recv()沒有發現任何資料,或send()呼叫無法立即傳送資料,那麼將引起socket.error異常。
s.makefile() 建立一個與該套接字相關連的檔案
注意事項:

  1. Python3以後,socket傳遞的都是bytes型別的資料,字串需要先轉換一下,string.encode()即可;另一端接收到的bytes資料想轉換成字串,只要bytes.decode()一下就可以。
  2. 在正常通訊時,accept()和recv()方法都是阻塞的。所謂的阻塞,指的是程式會暫停在那,一直等到有資料過來。
    socket程式設計思路:
    服務端:
  3. 建立套接字,繫結套接字到本地IP與埠:socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.bind()
  4. 開始監聽連線:s.listen()
  5. 進入迴圈,不斷接受客戶端的連線請求:s.accept()
  6. 接收傳來的資料,或者傳送資料給對方:s.recv() , s.sendall()
  7. 傳輸完畢後,關閉套接字:s.close()
    客戶端:
  8. 建立套接字,連線伺服器地址:socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()
  9. 連線後傳送資料和接收資料:s.sendall(), s.recv()
  10. 傳輸完畢後,關閉套接字:s.close()
    Python的socket程式設計,通常可分為TCP和UDP程式設計兩種,前者是帶連線的可靠傳輸服務,每次通訊都要握手,結束傳輸也要揮手,資料會被檢驗,是使用最廣的通用模式;後者是不帶連線的傳輸服務,簡單粗暴,不加控制和檢查的一股腦將資料傳送出去的方式,但是傳輸速度快,通常用於安全和可靠等級不高的業務場景,比如檔案下載。

資料庫程式設計:
DB-API 是一個規範. 它定義了一系列必須的物件和資料庫存取方式, 以便為各種各樣的底層資料庫系統和多種多樣的資料庫介面程式提供一致的訪問介面 。
Python DB-API使用流程:
• 引入 API 模組。
• 獲取與資料庫的連線。
• 執行SQL語句和儲存過程。
• 關閉資料庫連線。

實際程式設計中遇到的問題:
 Print輸出亂碼:
 字元的ascll碼 用ord(),ascll轉字元用 chr()
 提取出字典中的值 :如a = {‘name’:’值’} 使用命令 a.get(‘name’)


  1. A-Za-z ↩︎

  2. A-Za-z0-9 ↩︎

  3. 0-9 ↩︎