1. 程式人生 > >廖雪峰Python教程實戰篇-Day5

廖雪峰Python教程實戰篇-Day5

  1. async def handle_url_xxx(request):    
  2.     ...    
第二步,傳入檢視函式的引數要自己從request中獲取:
  1. url_param = request.match_info['key']    
  2. query_params = parse_qs(request.query_string)  
第三步,自行構造返回的Response物件:
  1. text = render('template', data)    
  2. return web.Response(text.encode('utf-8'))  
以上這些重複的過程,可以在新建的框架中封裝起來。1.2 新建框架編寫檢視函式
首先編寫一個構造檢視函式的裝飾器,其中傳遞、儲存URL資訊(path,method)
  1. # 建立檢視函式裝飾器,用來儲存、附帶URL資訊
  2. def Handler_decorator(path, *, method):  
  3.     def decorator(func):  
  4.         @functools.wraps(func)  
  5.         def warpper(*args, **kw):  
  6.             return func(*args, **kw)          
  7.         warpper.__route__ = path  
  8.         warpper.__method__ = method  
  9.         return warpper  
  10.     return decorator  
  11. # 偏函式。GET POST 方法的路由裝飾器
  12. get = functools.partial(Handler_decorator, method = 'GET')  
  13. post = functools.partial(Handler_decorator, method = 'POST')  
這樣就可以直接通過裝飾器,直接將一個函式對映成檢視函式。
  1. @get
  2. def View(request):    
  3.      return response    
1.3 編寫RequestHandler:處理request物件
我們已經完成了檢視函式裝飾器的編寫,但這遠遠不夠。檢視函式仍無法從request中獲取引數。所以我們還要從request物件中提取相應檢視函式所需的引數,並且檢視函式並非都是coroutine因此,需要定義一個能處理request請求的類來對檢視函式進行封裝,RequestHandlerRequestHandler是一個類,分析檢視函式所需的引數,再從request物件中將引數提取,呼叫檢視函式(URL處理函式),並返回web.Response物件。由於其定義了__call__()方法,其例項物件可以看作函式。用這樣一個RequestHandler類,就能處理各類request向對應檢視函式發起的請求了。1.3.1 解析檢視函式使用python自帶庫的inspect模組,解析檢視函式的引數
  1. # 使用inspect模組,檢查檢視函式的引數
  2. # inspect.Parameter.kind 型別:
  3. # POSITIONAL_ONLY          位置引數
  4. # KEYWORD_ONLY             命名關鍵詞引數
  5. # VAR_POSITIONAL           可選引數 *args
  6. # VAR_KEYWORD              關鍵詞引數 **kw
  7. # POSITIONAL_OR_KEYWORD    位置或必選引數
  8. def get_required_kw_args(fn):  # 獲取無預設值的命名關鍵詞引數
  9.     args = []  
  10.     ''''' 
  11.     def foo(a, b = 10, *c, d,**kw): pass 
  12.     sig = inspect.signature(foo) ==> <Signature (a, b=10, *c, d, **kw)> 
  13.     sig.parameters ==>  mappingproxy(OrderedDict([('a', <Parameter "a">), ...])) 
  14.     sig.parameters.items() ==> odict_items([('a', <Parameter "a">), ...)]) 
  15.     sig.parameters.values() ==>  odict_values([<Parameter "a">, ...]) 
  16.     sig.parameters.keys() ==>  odict_keys(['a', 'b', 'c', 'd', 'kw']) 
  17.     '''
  18.     params = inspect.signature(fn).parameters  
  19.     for name, param in params.items():  
  20.         # 如果檢視函式存在命名關鍵字引數,且預設值為空,獲取它的key(引數名)
  21.         if param.kind == inspect.Parameter.KEYWORD_ONLY and param.default == inspect.Parameter.empty:  
  22.             args.append(name)  
  23.     return tuple(args)  
  24. def get_named_kw_args(fn):  # 獲取命名關鍵詞引數
  25.     args = []  
  26.     params = inspect.signature(fn).parameters  
  27.     for name, param in params.items():  
  28.         if param.kind == inspect.Parameter.KEYWORD_ONLY:  
  29.             args.append(name)  
  30.     return tuple(args)  
  31. def has_named_kw_arg(fn):  # 判斷是否有命名關鍵詞引數
  32.     params = inspect.signature(fn).parameters  
  33.     for name, param in params.items():  
  34.         if param.kind == inspect.Parameter.KEYWORD_ONLY:  
  35.             returnTrue
  36. def has_var_kw_arg(fn):  # 判斷是否有關鍵詞引數
  37.     params = inspect.signature(fn).parameters  
  38.     for name, param in params.items():  
  39.         if param.kind == inspect.Parameter.VAR_KEYWORD:  
  40.             returnTrue
  41. def has_request_arg(fn):   # 判斷是否含有名叫'request'的引數,且位置在最後
  42.     params = inspect.signature(fn).parameters  
  43.     found = False
  44.     for name, param in params.items():  
  45.         if name == 'request':  
  46.             found = True
  47.             continue
  48.         if found and (  
  49.             param.kind != inspect.Parameter.VAR_POSITIONAL and
  50.             param.kind != inspect.Parameter.KEYWORD_ONLY and
  51.             param.kind != inspect.Parameter.VAR_KEYWORD):  
  52.             # 若判斷為True,表明param只能是位置引數。且該引數位於request之後,故不滿足條件,報錯。
  53.             raise ValueError('request parameter must be the last named parameter in function:%s%s' % (fn.__name__, str(sig)))  
  54.     return found  
1.3.2 提取request中的引數request是經aiohttp包裝後的物件。其本質是一個HTTP請求請求狀態(status)請求首部(header)內容實體(body)三部分組成。我們需要的引數包含在內容實體以及請求狀態URI中。request物件封裝了HTTP請求,可以通過request的屬性調取值。RequestHandler需要處理以下問題:1、確定HTTP請求的方法(’POST’or’GET’)(用request.method獲取)2、根據HTTP請求的content_type欄位,選用不同解析方法獲取引數。(用request.content_type獲取)3、將獲取的引數經處理,使其完全符合檢視函式接收的引數形式4、呼叫檢視函式
  1. # 定義RequestHandler從檢視函式中分析其需要接受的引數,從web.Request中獲取必要的引數
  2. # 呼叫檢視函式,然後把結果轉換為web.Response物件,符合aiohttp框架要求
  3. class RequestHandler(object):  
  4.     def __init__(self, app, fn):  
  5.         self._app = app  
  6.         self._func = fn  
  7.         self._required_kw_args = get_required_kw_args(fn)  
  8.         self._named_kw_args = get_named_kw_args(fn)  
  9.         self._has_request_arg = has_request_arg(fn)  
  10.         self._has_named_kw_arg = has_named_kw_arg(fn)  
  11.         self._has_var_kw_arg = has_var_kw_arg(fn)  
  12.     # 1.定義kw,用於儲存引數
  13.     # 2.判斷檢視函式是否存在關鍵詞引數,如果存在根據POST或者GET方法將request請求內容儲存到kw
  14.     # 3.如果kw為空(說明request無請求內容),則將match_info列表裡的資源對映給kw;若不為空,把命名關鍵詞引數內容給kw
  15.     # 4.完善_has_request_arg和_required_kw_args屬性
  16.     async def __call__(self, request):  
  17.         kw = None

    相關推薦

    雪峰Python教程實戰-Day5

    async def handle_url_xxx(request):        ...    第二步,傳入檢視函式的引數要自己從request中獲取:url_param = request.match_info['key']    query_params = parse_qs(request.query

    部落格記錄雪峰python教程的習題(二)

    函數語言程式設計 高階函式—–sorted 首先我們需要明確一點就是sorted()函式是作用於一個列表,對列表中的每一項元素進行排序,因為sorted本身的作用就是對元素排序,如果後面還有key=function ,則是先對列表中的每一項元素按照fun

    Python 學習從雪峰 Python教程開始

    https info python 學習 分享 圖片 png wiki src ima https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 Python 學習

    雪峰--python教程:筆記三

    [1] 小寫 對象 gin collect 內置函數 返回值 python 字典 通過 高級特性:前面我們簡單的聊了一下Python的數據類型、語句和函數,接下來來聊聊Python的高級特性 切片:取一個list、tuple、str一部分內容是很常見的操作,而切片操作,可以

    關於雪峰python教程中__geattr__()函式的一些理解

    原文: 利用完全動態的__getattr__,我們可以寫出一個鏈式呼叫: `class Chain(object): def __init__(self, path=''): self._path = path def __getattr__(self, path):

    Python 3 學習(一)—— 基礎:雪峰 Python 教程學習筆記

    文章目錄 Python教程 值型別和引用型別 列表和字典的基本操作 列表 元組 字典 Set 函式 內建函式 定義函式 空函式 引數檢查 定

    雪峰Python教程答案

    課程地址:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 感謝廖老師。 高階特性 生成器 generator 楊輝三角 楊輝三角定義如下:

    雪峰Python教程筆記(一)

    感謝廖老師精彩的Python教程,收益良多,感謝感謝! 整理筆記,以備後續複習,第一部分一直到模組結束,整理如下,其中大量的單引號是有問題的,由於word直接打的,嫌麻煩,沒有都進行修正,請見諒 1、a = ‘XYZ’ 的過程是先在記憶體中建立一個’XYZ’字串,然後

    【Python3.6】:雪峰python教程轉換成 PDF

    開始寫爬蟲前,我們先來分析一下該網站https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 的頁面結構,網頁的左側是教程的目錄大綱,每個 URL 對應到右邊的一篇文章,右側上

    雪峰 python教程 課後題 切片】利用切片操作,實現一個trim()函式,去除字串首尾的空格,注意不要呼叫str的strip()方法:

    #encoding:utf-8 #定義一個函式,用來去除字串首尾的空格 def trim(s):     '''首先判斷該字串是否為空,如果為空,就返回該字串,     如果不為空的話,就判斷字串首尾字元是否為空,     如果為空,就使用遞迴再次呼叫該函式trim(),否

    雪峰python教程之用map函式實現大小寫轉換

    題目:利用map()函式,把使用者輸入的不規範的英文名字,變為首字母大寫,其他小寫的規範名字。輸入:['adam', 'LISA', 'barT'],輸出:['Adam', 'Lisa', 'Bart'] def normalize(name): return n

    雪峰python教程day3-編寫ORM

    首先要明確: ORM的編寫較為複雜,但編寫完成後使用介面進行呼叫則顯得非常簡單。並且ORM編寫模式基本為 -Field模組 -元類MetaClass -基類Model 有著較為固定的寫法,沒必要重複造輪子,能複用儘量複用。重要的是要理解元類這塊硬骨頭的妙用。 基

    雪峰 python教程 課後題改編】利用map()函式,把使用者輸入的不規範的英文名字,變為首字母大寫,其他小寫的規範名字

    原題目: # -*- coding: utf-8 -*- #輸入名字,變成首字母大寫,其他字母小寫的標準格式 def normalize(name): str1 = '' for i, ch in enumerate(name): if i

    雪峰python實戰專案_Day1

    #! app.py import logging;logging.basicConfig(level=logging.INFO) import asyncio, os, json, time from datetime import datetime from aioh

    雪峰Python 2.X 教程

    Python簡介Python是著名的“龜叔”Guido van Rossum在1989年聖誕節期間,為了打發無聊的聖誕節而編寫的一個程式語言。當你用一種語言開始作真正的軟體開發時,你除了編寫程式碼外,還需要很多基本的已經寫好的現成的東西,來幫助你加快開發進度。比如說,要編寫一

    雪峰Python學習筆記——使用元類

    ram form 創建對象 字典 comm params int name 學習筆記 元類(MetaClasses) 元類提供了一個改變Python類行為的有效方式。 元類的定義是“一個類的類”。任何實例是它自己的類都是元類。 class demo(object):

    雪峰python摘錄4

    生成 結果 api cnblogs fun 相關 cap object log 1、直接作用於for循環的對象統稱為可叠代對象:Iterable。 可以被next()函數調用並不斷返回下一個值的對象稱為叠代器:Iterator。 2、生成器都是Iterator對象,但

    雪峰python摘錄5

    新的 aps ret col 出錯 簽名 一個 復制 div 1、假設我們要增強now()函數的功能,比如,在函數調用前後自動打印日誌,但又不希望修改now()函數的定義,這種在代碼運行期間動態增加功能的方式,稱之為“裝飾器”(Decorator)。 2、由於log()是一

    雪峰python摘錄6

    rar art ocs 沒有 概念 註意 表示 tar 完全 1 def now(): 2 print(‘hello‘) 3 4 import functools 5 6 def log(func): 7 @functools.wraps

    雪峰python摘錄二輪2

    預編譯 父類 空字符串 返回 提交 update fetch 出了 運行時 1 >>> def set_age(self, age): # 定義一個函數作為實例方法 2 ... self.age = age 3 ... 4 >>>