最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

200行自定義python異步非阻塞Web框架

 更新時間:2017年03月15日 10:26:37   作者:武沛齊  
本篇將使用200行代碼完成一個微型異步非阻塞Web框架:Snow。具有很好的參考價值,下面跟著小編一起來看下吧

Python的Web框架中Tornado以異步非阻塞而聞名。本篇將使用200行代碼完成一個微型異步非阻塞Web框架:Snow。

一、源碼

本文基于非阻塞的Socket以及IO多路復用從而實現異步非阻塞的Web框架,其中便是眾多異步非阻塞Web框架內部原理。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
import socket
import select
import time
class HttpResponse(object):
 """
 封裝響應信息
 """
 def __init__(self, content=''):
  self.content = content
  self.headers = {}
  self.cookies = {}
 def response(self):
  return bytes(self.content, encoding='utf-8')
class HttpNotFound(HttpResponse):
 """
 404時的錯誤提示
 """
 def __init__(self):
  super(HttpNotFound, self).__init__('404 Not Found')
class HttpRequest(object):
 """
 用戶封裝用戶請求信息
 """
 def __init__(self, conn):
  self.conn = conn
  self.header_bytes = bytes()
  self.header_dict = {}
  self.body_bytes = bytes()
  self.method = ""
  self.url = ""
  self.protocol = ""
  self.initialize()
  self.initialize_headers()
 def initialize(self):
  header_flag = False
  while True:
   try:
    received = self.conn.recv(8096)
   except Exception as e:
    received = None
   if not received:
    break
   if header_flag:
    self.body_bytes += received
    continue
   temp = received.split(b'\r\n\r\n', 1)
   if len(temp) == 1:
    self.header_bytes += temp
   else:
    h, b = temp
    self.header_bytes += h
    self.body_bytes += b
    header_flag = True
 @property
 def header_str(self):
  return str(self.header_bytes, encoding='utf-8')
 def initialize_headers(self):
  headers = self.header_str.split('\r\n')
  first_line = headers[0].split(' ')
  if len(first_line) == 3:
   self.method, self.url, self.protocol = headers[0].split(' ')
   for line in headers:
    kv = line.split(':')
    if len(kv) == 2:
     k, v = kv
     self.header_dict[k] = v
class Future(object):
 """
 異步非阻塞模式時封裝回調函數以及是否準備就緒
 """
 def __init__(self, callback):
  self.callback = callback
  self._ready = False
  self.value = None
 def set_result(self, value=None):
  self.value = value
  self._ready = True
 @property
 def ready(self):
  return self._ready
class TimeoutFuture(Future):
 """
 異步非阻塞超時
 """
 def __init__(self, timeout):
  super(TimeoutFuture, self).__init__(callback=None)
  self.timeout = timeout
  self.start_time = time.time()
 @property
 def ready(self):
  current_time = time.time()
  if current_time > self.start_time + self.timeout:
   self._ready = True
  return self._ready
class Snow(object):
 """
 微型Web框架類
 """
 def __init__(self, routes):
  self.routes = routes
  self.inputs = set()
  self.request = None
  self.async_request_handler = {}
 def run(self, host='localhost', port=9999):
  """
  事件循環(huán)
  :param host:
  :param port:
  :return:
  """
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  sock.bind((host, port,))
  sock.setblocking(False)
  sock.listen(128)
  sock.setblocking(0)
  self.inputs.add(sock)
  try:
   while True:
    readable_list, writeable_list, error_list = select.select(self.inputs, [], self.inputs,0.005)
    for conn in readable_list:
     if sock == conn:
      client, address = conn.accept()
      client.setblocking(False)
      self.inputs.add(client)
     else:
      gen = self.process(conn)
      if isinstance(gen, HttpResponse):
       conn.sendall(gen.response())
       self.inputs.remove(conn)
       conn.close()
      else:
       yielded = next(gen)
self.async_request_handler[conn] = yielded
    self.polling_callback()
except Exception as e:
   pass
  finally:
   sock.close()
def polling_callback(self):
  """
  遍歷觸發(fā)異步非阻塞的回調函數
  :return:
  """
  for conn in list(self.async_request_handler.keys()):
   yielded = self.async_request_handler[conn]
   if not yielded.ready:
    continue
   if yielded.callback:
    ret = yielded.callback(self.request, yielded)
    conn.sendall(ret.response())
   self.inputs.remove(conn)
   del self.async_request_handler[conn]
   conn.close()
 def process(self, conn):
  """
  處理路由系統(tǒng)以及執(zhí)行函數
  :param conn:
  :return:
  """
  self.request = HttpRequest(conn)
  func = None
  for route in self.routes:
   if re.match(route[0], self.request.url):
    func = route[1]
    break
  if not func:
   return HttpNotFound()
  else:
   return func(self.request)
snow.py

二、使用

1. 基本使用

from snow import Snow
from snow import HttpResponse
def index(request):
return HttpResponse('OK')
routes = [
 (r'/index/', index),
]
app = Snow(routes)
app.run(port=8012)

2.異步非阻塞:超時

from snow import Snow
from snow import HttpResponse
from snow import TimeoutFuture
request_list = []
def async(request):
 obj = TimeoutFuture(5)
 yield obj
def home(request):
 return HttpResponse('home')
routes = [
 (r'/home/', home),
 (r'/async/', async),
]
app = Snow(routes)
app.run(port=8012)

3.異步非阻塞:等待

基于等待模式可以完成自定制操作

from snow import Snow
from snow import HttpResponse
from snow import Future
request_list = []
def callback(request, future):
 return HttpResponse(future.value)
def req(request):
 obj = Future(callback=callback)
 request_list.append(obj)
 yield obj
def stop(request):
 obj = request_list[0]
 del request_list[0]
 obj.set_result('done')
 return HttpResponse('stop')
routes = [
 (r'/req/', req),
 (r'/stop/', stop),
]
app = Snow(routes)
app.run(port=8012)

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關文章

  • 淺析使用Python操作文件

    淺析使用Python操作文件

    文件操作對編程語言的重要性不用多說,如果數據不能持久保存,信息技術也就失去了意義。按照本人經驗,IO也是蠻頭疼的一件事,因為不會用得太多,所以總是記不住API,每次都要重新google就會打斷思路,還不一定每次都快速得到正確的文章。
    2017-07-07
  • Python如何在單元測試中給對象打補丁

    Python如何在單元測試中給對象打補丁

    這篇文章主要介紹了Python如何在單元測試中給對象打補丁,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-08-08
  • Python LMDB庫的使用示例

    Python LMDB庫的使用示例

    這篇文章主要介紹了Python LMDB庫的使用示例,幫助大家更好的利用python處理數據庫,感興趣的朋友可以了解下
    2021-02-02
  • PyCharm實現遠程調試的全過程(附圖文講解)

    PyCharm實現遠程調試的全過程(附圖文講解)

    這篇文章主要介紹了PyCharm實現遠程調試的全過程,文中通過圖文結合的方式給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-05-05
  • python按順序重命名文件并分類轉移到各個文件夾中的實現代碼

    python按順序重命名文件并分類轉移到各個文件夾中的實現代碼

    這篇文章主要介紹了python按順序重命名文件并分類轉移到各個文件夾中,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Python實現批量下載圖片的方法

    Python實現批量下載圖片的方法

    這篇文章主要介紹了Python實現批量下載圖片的方法,涉及Python基于urllib、urllib2及re等模塊獲取URL及正則匹配下載圖片的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • python實現簡單的單變量線性回歸方法

    python實現簡單的單變量線性回歸方法

    今天小編就為大家分享一篇python實現簡單的單變量線性回歸方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python+django實現文件上傳

    Python+django實現文件上傳

    本系列以可操作性為主,介紹如何通過django web框架來實現一些簡單的功能。每一篇文章都具有完整性和獨立性。使用新手在動手做的過程中體會web開發(fā)的過程,過程中細節(jié)請參考相關文檔。
    2016-01-01
  • 基于Python和Tkinter實現高考倒計時功能

    基于Python和Tkinter實現高考倒計時功能

    隨著高考的臨近,每個考生都在緊鑼密鼓地復習,這時候,一款實用的倒計時軟件能有效幫助你規(guī)劃剩余時間,提醒你不要浪費每一分每一秒,今天,我們來聊聊一款基于Python和Tkinter開發(fā)的高考倒計時軟件,功能簡單卻極具實用性,讓你在緊張的備考過程中不再迷失
    2025-03-03
  • Python使用watchfiles實現監(jiān)控目錄變更

    Python使用watchfiles實現監(jiān)控目錄變更

    在工作中難免會碰到這樣的需求,監(jiān)控指定目錄,下面小編就來和大家介紹一下如何利用watchfiles 模塊實現監(jiān)控目錄的變更,感興趣的可以了解下
    2023-09-09

最新評論

成安县| 清原| 长沙县| 阿尔山市| 台山市| 锡林浩特市| 华坪县| 宜兴市| 剑川县| 若尔盖县| 伊金霍洛旗| 绥棱县| 轮台县| 达拉特旗| 竹北市| 阆中市| 宜兰县| 寿宁县| 工布江达县| 怀柔区| 连城县| 舞阳县| 措美县| 泽州县| 江永县| 和静县| 宁安市| 青铜峡市| 巍山| 同江市| 林周县| 怀宁县| 邵武市| 浦北县| 西吉县| 大埔区| 尉犁县| 绵竹市| 浮梁县| 四子王旗| 宜章县|