網絡程序出現的比互聯網要早不少,實現方式主要依靠網絡上不一樣主機間進程的通訊,通訊協議最重要的是TCP/IP協議。在這兩個協議基礎上還有不少更高級的協議,包括HTTP、SMTP等。要進行兩個主機間的網絡通訊,必須四個元素:源地址、源端口號、目的地址、目的端口號。php
Socket是網絡編程一個抽象概念,一般咱們用一個Socket表示「打開了一個網絡連接」,而打開一個Socket須要知道目標計算機的IP地址和端口號,再指定協議類型便可。示例代碼實現了一個服務端和客戶端,服務端將客戶端發送的內容回顯給客戶端,一切都是在命令行下執行。圖形界面原理同樣。html
import socket import threading import time #服務端代碼 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 9999)) #開始監聽端口,參數表示最大鏈接數 s.listen(5) print("Waiting for connection...") def tcplink(sock, addr): print('Accept new connection from %s:%s...' % addr) sock.send(b'Welcome!') while True: data = sock.recv(1024) time.sleep(1) if not data or data.decode('utf-8') == 'exit': break sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8')) sock.close() print('Connection from %s:%s closed.' % addr) while True: sock, addr = s.accept() t = threading.Thread(target=tcplink, args=(sock, addr)) t.start()
客戶端代碼前端
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 創建鏈接: s.connect(('127.0.0.1', 9999)) # 接收歡迎消息: print(s.recv(1024).decode('utf-8')) for data in [b'Michael', b'Tracy', b'Sarah']: # 發送數據: s.send(data) print(s.recv(1024).decode('utf-8')) s.send(b'exit') s.close()
TCP創建了雙方之間的可靠鏈接,通訊雙方均可以用流的方式發送數據。UDP則是面相無鏈接的協議,使用UDP協議時,不須要創建鏈接,只須要知道對方的IP和端口號,就能夠直接發送數據包。可是對方是否可以收到就不知道了。它的優勢是速度快。python
服務端代碼web
import socket import threading import time s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 綁定端口: s.bind(('127.0.0.1', 9999)) print('Bind UDP on 9999...') while True: # 接收數據: data, addr = s.recvfrom(1024) print('Received from %s:%s.' % addr) s.sendto(b'Hello, %s!' % data, addr)
客戶端代碼正則表達式
import socket import threading import time s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for data in [b'Michael', b'Tracy', b'Sarah']: # 發送數據: s.sendto(data, ('127.0.0.1', 9999)) # 接收數據: print(s.recv(1024).decode('utf-8')) s.close()
作了一個簡單的對比,可見UDP的傳輸方式比TCP快了不少。編程
隨着互聯網流行起來的B/S模式是Web開發的主要內容,包括客戶端展示(HTML、CSS、JAVASCRIPT)以及服務端處理(靜態內容、CGI、動態語言)。Python提供了不少Web開發框架,可以爲咱們提供Web開發的快速支持。服務器
開始WEB開發的話我以爲最好從HTML入手,而後瞭解HTTP協議,這些熟悉以後逐步熟悉CSS、Javascript,而後告終合後臺編程語言,完成本身編寫網站的小目標。網絡
筆者是從PHP學習開始Web開發的,接觸Python的Web開發還沿用PHP的思路會產生一些迷惑。PHP從產生之初就是做爲Web開發語言而設計的,PHP是做爲Apache的模塊來進行請求處理和響應的,與HTTP相關的不少基礎處理都是由Apache完成的,mod_php模塊與其對接生成相似$_POST,$_GET的對象供PHP腳本使用。app
Python有所不一樣,Python是做爲一種通用腳本處理語言產生的,因此它可以完成的工做更多,也能夠做爲Web開發語言,只是方式不一樣。若是Python做爲服務端腳本語言,能夠分幾個層次:若是Python負責處理全部的事務,包括TCP連接、邏輯處理、內容響應,Python也是能夠勝任的,可是這樣開發要作的工做就很是多;若是Python只是負責生成HTML文檔,前端使用Apache等,Pyhon只須要負責文檔解析。實現這個層次,是由於Python提供了WSGI接口(Web Server Gateway Interface),這時Python的焦點放在接口處理和Web邏輯處理上。第三個層次就是使用Python的Web框架,如今有不少成熟的框架,包括Django、Flask等。這樣,Python就主要關注Web處理,包括URL以及對應的函數處理。
先看一下使用WSGI接口編寫簡單的Web程序,返回一個簡單的文字。
# server.py # 從wsgiref模塊導入: from wsgiref.simple_server import make_server # 導入咱們本身編寫的application函數: from hello import application # 建立一個服務器,IP地址爲空,端口是8000,處理函數是application: httpd = make_server('', 8000, application) print('Serving HTTP on port 8000...') # 開始監聽HTTP請求: httpd.serve_forever()
# hello.py def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) body = '<h1>Hello, %s!</h1>' % (environ['PATH_INFO'][1:] or 'web') return [body.encode('utf-8')]
使用WSGI的方式來進行Web開發,須要花不少精力來處理請求和響應的對應關係,這個時候能夠引入框架。這裏以Web.py框架爲例。
import web urls = ( '/(.*)', 'hello' ) app = web.application(urls, globals()) class hello: def GET(self, name): if not name: name = 'World' return 'Hello, ' + name + '!' if __name__ == "__main__": app.run()
因而可知,使用框架後,咱們能夠將精力放在URL和對應的處理函數上。
正則表達式提及來是一個能夠講好久的話題,這裏簡單說一下 Python 中的使用。
Python提供re模塊,包含全部正則表達式的功能。建議全部處理正則的部分都使用```r```開頭,這樣就不須要考慮轉義的問題。
>>> import re >>> re.match(r'^\d{3}\-\d{3,8}$', '010-12345') <_sre.SRE_Match object; span=(0, 9), match='010-12345'> >>> re.match(r'^\d{3}\-\d{3,8}$', '010 12345') >>>
若是匹配則返回一個Match對象,沒找到則返回None。
可使用正則的切分字符串
>>> re.split(r'\s+', 'a b c') ['a', 'b', ‘c']
正則表達式中提供了()
進行匹配結果的分組,若是正則表達式中定義了組,就可使用Match
對象的group()
方法提取子串。group(0)
表示的是原始字符串。
>>> t = '19:05:30' >>> m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t) >>> m.groups() ('19', '05', '30')
datetime是Python處理日期和時間的標準庫。日期操做中,經常使用的包括獲取當前日誌、建立一個日期、計算兩個日期的差值、判斷日期的類型、日期與時間戳的相互轉換、字符串與日期類型的相互轉換,這些基本上看看例子就能夠掌握。
在計算機中,時間其實是用數字表示的。咱們把1970年1月1日 00:00:00 UTC+00:00時區的時刻稱爲epoch time,記爲0(1970年之前的時間timestamp爲負數),當前時間就是相對於epoch time的秒數,稱爲timestamp。timestamp 與時區沒有關係,datetime與時區有關係。
字符串'%Y-%m-%d %H:%M:%S'規定了日期和時間部分的格式。詳細的說明請參考Python文檔。字符串轉換爲日期類型後,默認是沒有帶時區信息的。
from datetime import datetime, timedelta, timezone # 獲取當前時間 now = datetime.now() print(now) # 建立一個指定的日期 wt = datetime(2017,4,12,14,5,15) print(wt) # 將日期類型轉換爲時間戳 print( wt.timestamp() ) # 將時間戳轉換爲日期,加了一個小時 print( datetime.fromtimestamp(wt.timestamp() + 60*60 ) ) # 字符串轉換爲日期類型 cday = datetime.strptime('2017-4-12 18:19:59', '%Y-%m-%d %H:%M:%S') print(cday) # 將日期類型格式化爲字符串顯示 print(now.strftime('%A, %B, %d, %H:%m')) # 日期類型也能夠直接使用 + - 進行運算,引入timedelta能夠計算差值 print(now - timedelta(days=1)) print(now + timedelta(days=1, hours=2))
collections 是 Python 內建的一個集合模塊,提供了許多有用的集合類。包括 namedtuple、deque
tuple 能夠表示不變集合,可是不方便從名稱上看出用途。經過使用namedtuple函數,能夠建立一個自定義的tuple對象,規定了tuple的個數,而且能夠經過屬性來訪問元素。
使用 list 存儲數據時,,按索引訪問元素很快,可是插入和刪除元素就很慢了,由於list是線性存儲,數據量大的時候,插入和刪除效率很低。deque是爲了高效實現插入和刪除操做的雙向列表,適合用於隊列和棧。deque除了實現list的append()
和pop()
外,還支持appendleft()
和popleft()
,這樣就能夠很是高效地往頭部添加或刪除元素。