python如何使頁面靜態化的簡單介紹

本文目錄一覽:

純 Python 寫一個 Web 框架,就是這麼簡單

造輪子是最好的一種學習方式,本文嘗試從0開始造個Python Web框架的輪子,我稱它為 ToyWebF 。

本文操作環境為:MacOS,文中涉及的命令,請根據自己的系統進行替換。

ToyWebF的簡單特性:

下面我們來實現這些特性。

首先,我們需要安裝gunicorn,回憶一下Flask框架,該框架有內置的Web服務器,但不穩定,所以上線時通常會替換成uWSGI或gunicorn,這裡不搞這個內置Web服務,直接使用gunicorn。

我們創建新的目錄與Python虛擬環境,在該虛擬環境中安裝gunicorn

在啥都沒有的情況下,構建最簡單的Web服務,在ToyWebF目錄下,創建app.py與api.py文件,寫入下面代碼。

運行 gunicorn app:app 訪問 ,可以看見 Hello, World! ,但現在請求體中的參數在environ變量中,難以解析,我們返回的response也是bytes形式。

我們可以使用webob庫,將environ中的數據轉為Request對象,將需要返回的數據轉為Response對象,處理起來更加直觀方便,直接通過pip安裝一下。

然後修改一下API類的 __call__方法 ,代碼如下。

上述代碼中,通過webob庫的Request類將environ對象(請求的環境信息)轉為容易處理的request,隨後調用handle_request方法對request進行處理,處理的結果,通過response對象返回。

handle_request方法在ToyWebF中非常重要,它會匹配出某個路由對應的處理方法,然後調用該方法處理請求並將處理的結果返回,在解析handle_request前,需要先討論路由註冊實現,代碼如下。

其實就是將路由和方法存到self.routes字典中,可以通過route裝飾器的形式將路由和方法關聯,也可以通過add_route方法關聯,在app.py中使用一下。

因為url中可以存在變量,如 @app.route(“/hello/{name}”) ,所以在匹配時,需要進行解析,可以使用正則匹配的方式進行匹配,parse這個第三方庫已經幫我們實現了相應的正則匹配邏輯,pip安裝使用一下則可。

這裡定義find_handler方法來實現對self.routes的遍歷。

了解了路由與方法關聯的原理後,就可以實現handle_request方法,該方法主要的路徑就是根據路由調度對應的方法,代碼如下。

在該方法中,首先實例化webob庫的Response對象,然後通過self.find_handler方法獲取此次請求路由對應的方法和對應的參數,比如。

它將返回hello方法對象和name參數,如果是 /hello/二兩 ,那麼name就是二兩。

因為route裝飾器可能裝飾器的類對象,比如。

此時self.find_handler方法返回的hanler就是個類,但我們希望調用的是類中的get、post、delete等方法,所以需要一個簡單的判斷邏輯,通過inspect.isclass方法判斷handler如果是類對象,那麼就通過getattr方法獲取類對象實例的中對應的請求方法。

如果類對象中沒有該方法屬性,則拋出該請求類型不被允許的錯誤,如果不是類對象或類對象中存在該方法屬性,則直接調用則可。

此外,如果方法的路由並沒有註冊到self.routes中,即404的情況,定義了defalut_response方法返回其中內容,代碼如下。

如果handle_request方法中調度的過程出現問題,則直接raise將錯誤拋出。

至此,一個最簡單的web服務就編寫完成了。

回顧Flask,Flask可以支持HTML、CSS、JavaScript等靜態文件,利用模板語言,可以構建出簡單但美觀的Web應用,我們讓TopWebF也支持這一功能,最終實現圖中的網站,完美兼容靜態文件。

Flask使用了jinja2作為其html模板引擎,ToyWebF同樣使用jinja2,jinja2其實實現一種簡單的DSL(領域內語言),讓我們可以在HTML中通過特殊的語法改變HTML的結構,該項目非常值得研究學習。

首先 pip install jinja2 ,然後就可以使用它了,在ToyWebF項目目錄中創建templates目錄,以該目錄作為默認的HTML文件根目錄,代碼如下。

首先利用jinja2的FileSystemLoader類將file system中的某個文件夾作為loader,然後初始化Environment。

在使用的過程中(即調用template方法),通過get_template方法獲得具體的某個模板並通過render方法將對應的內容傳遞給模板中的變量。

這裡我們不寫前端代碼,直接去互聯網中下載模板,這裡下載了Bootstrap提供的免費模板,可以自行去 下載,下載完後,你會獲得index.html以及對應的css、jss、img等文件,將index.html移動到ToyWebF/templates中並簡單修改了一下,添加一些變量。

然後在app.py文件中為index.html定義路由以及需要的參數。

至此html文件的支持就完成了,但此時的html無法正常載入css和js,導致頁面布局非常醜陋且交互無法使用。

接着就讓ToyWebF支持css、js,首先在ToyWebF目錄下創建static文件夾用於存放css、js或img等靜態文件,隨後直接將前面下載的模板,其中的靜態文件複製到static中則可。

通過whitenoise第三方庫,可以通過簡單的幾行代碼讓web框架支持css和js,不需要依賴nginx等服務,首先 pip install whitenoise ,隨後修改API類的 __init__ 方法,代碼如下。

其實就是通過WhiteNoise將self.wsgi_app方法包裹起來,在調用API的 __call__ 方法時,直接調用self.whitenoise。

此時,如果請求web服務獲取css、js等靜態資源,WhiteNoise會獲取其內容並返回給client,它在背後會匹配靜態資源在系統中對應的文件並將其讀取返回。

至此,一開始的網頁效果就實現好了。

web服務如果出現500時,默認會返回 internal server error ,這顯得比較丑,為了讓框架使用者可以自定義500時返回的錯誤,需要添加一些代碼。

首先API初始化時,初始self.exception_handler對象並定義對應的方法添加自定義的錯誤

在handler_request方法進行請求調度時,調度的方法執行邏輯時報500,此時不再默認將錯誤拋出,而是先判斷是否有自定義錯誤處理。

在app.py中,自定義錯誤返回方法,如下。

custom_exception_handler方法只返回自定義的一段話,你完全可以替換成美觀的template。

我們可以實驗性定義一個路由來看效果。

Web服務的中間件也可以理解成鉤子,即在請求前可以對請求做一些處理或者返回Response前對Response做一下處理。

為了支持中間件,在TopWebF目錄下創建middleware.py文件,在編寫代碼前,思考一下如何實現?

回顧一下現在請求的調度邏輯。

1.通過routes裝飾器關聯路由和方法 2.通過API.whitenoise處理 3.如果是請求API接口,那麼會將參數傳遞給API.wsgi_app 4.API.wsgi_app最終會調用API.handle_request方法獲取路由對應的方法並調用該方法執行相應的邏輯

如果希望在request前以及response後做相應的操作,那麼其實就需要讓邏輯在API.handle_request前後執行,看一下代碼。

其中add方法會實例化Middleware對象,該對象會將當前的API類實例包裹起來。

Middleware.handle_request方法其實就是在self.app.handle_request前調用self.process_request方法處理request前的數據以及調用self.process_response處理response後的數據,而核心的調度邏輯,依舊交由API.handle_request方法進行處理。

這裡的代碼可能會讓人感到疑惑, __call__ 方法和handle_request方法中都有self.app.handle_request(request),但其調用對象似乎不同?這個問題暫時放一下,先繼續完善代碼,然後再回來解釋。

接着在api.py中為API創建middleware屬性以及添加新中間件的方法。

隨後,在app.py中,自定義一個簡單的中間件,然後調用add_middleware方法將其添加。

定義好中間件後,在請求調度時,就需要使用中間件,為了兼容靜態文件的情況,需要對css、js、ing文件的請求路徑做一下兼容,在其路徑中加上/static前綴

緊接着,修改API的 __call__ ,兼容中間件和靜態文件,代碼如下。

至此,中間件的邏輯就完成了。

但代碼中依舊有疑惑,Middleware類中的 __call__ 方法和handle_request方法其調用的self.app到底是誰?

為了方便理解,這裡一步步拆解。

如果沒有添加新的中間件,那麼請求的調度邏輯如下。

在沒有添加中間件的情況下,self.app其實就是API本身,所以 middleware.__call__ 中的self.app.handle_request就是調用API.handle_request。

如果添加了新的中間件,如上述代碼中添加了名為SimpleCustomMiddleware的中間件,此時的請求調度邏輯如下。

因為註冊中間件時,Middleware.add方法替換了原始Middleware實例中的app對象,將其替換成了SimpleCustomMiddleware,而SimpleCustomMiddleware也有app對象,SimpleCustomMiddleware中的app對象,才是API類實例。

在請求調度的過程中,就會觸發Middleware類的handle_request方法,該方法就會執行中間件相應的邏輯去處理request和response中的數據。

當然,你可以通過Middleware.add方法添加多個中間件,這就會構成棧式調用的效果,代碼如下。

啟動web服務後,其執行效果如下。

python 為什麼要使用靜態方法

Python使用靜態方法類似函數工具使用,一般盡量少用靜態方法。

Python的靜態方法和類成員方法都可以被類或實例訪問,兩者概念不容易理清,但還是有區別的:

1)靜態方法無需傳入self參數,類成員方法需傳入代表本類的cls參數;

2)從第1條,靜態方法是無法訪問實例變量的,而類成員方法也同樣無法訪問實例變量,但可以訪問類變量;

3)靜態方法有點像函數工具庫的作用,而類成員方法則更接近類似Java面向對象概念中的靜態方法。

3種python3的canny邊緣檢測之靜態,可調節和自適應

先看高級版的python3的canny的自適應邊緣檢測:

內容:

1 canny的邊緣檢測的介紹。

2 三種方法的canny的邊緣檢測,由淺入深地介紹:固定值的靜態,可自調節的,自適應的。

說明:

1 環境:python3.8、opencv4.5.3和matplotlib3.4.3。

2 圖片:來自品閱網正版免費圖庫。

3 實現自適應閾值的canny邊緣檢測的參考代碼和文章:

上述的代碼,本機均有報錯,故對代碼進行修改,注釋和運行。

初級canny:

1 介紹:opencv中給出了canny邊緣檢測的接口,直接調用:

即可得到邊緣檢測的結果ret,其中,t1,t2是需要人為設置的閾值。

2 python的opencv的一行代碼即可實現邊緣檢測。

3 Canny函數及使用:

4 Canny邊緣檢測流程:

去噪 — 梯度 — 非極大值抑制 — 滯後閾值

5 代碼:

6 操作和過程:

7 原圖:

8 疑問:

ret = cv2.canny(img,t1,t2),其中,t1,t2是需要人為設置的閾值,一般人怎麼知道具體數值是多少,才是最佳的呀?所以,這是它的缺點。

中級canny:

1 中級canny,就是可調節的閾值,找到最佳的canny邊緣檢測效果。

2 採用cv2.createTrackbar來調節閾值。

3 代碼:

4 操作和效果:

5 原圖:

高級canny:

1 自適應canny的算法:

ret = cv2.canny(img,t1,t2)

即算法在運行過程中能夠自適應地找到較佳的分割閾值t1,t2。

2 文件結構:

3 main.py代碼:

4 dog.py代碼:

5 bilateralfilt.py代碼:

6 原圖:

7 效果圖:本文第一個gif圖,此處省略。

小結:

1 本文由淺入深,總結的很好,適合收藏。

2 對於理解python的opencv的canny的邊緣檢測,很有幫助。

3 本文高級版canny自適應的算法參考2篇文章,雖然我進行代碼的刪除,注釋,修改,優化等操作,故我不標註原創,對原作者表達敬意。

4 自己總結和整理,分享出來,希望對大家有幫助。

如何用python抓取這個網頁的內容?

Python實現常規的靜態網頁抓取時,往往是用urllib2來獲取整個HTML頁面,然後從HTML文件中逐字查找對應的關鍵字。如下所示:

複製代碼代碼如下:

import urllib2

url=”網址”

up=urllib2.urlopen(url)#打開目標頁面,存入變量up

cont=up.read()#從up中讀入該HTML文件

key1=’a href=”http’#設置關鍵字1

key2=”target”#設置關鍵字2

pa=cont.find(key1)#找出關鍵字1的位置

pt=cont.find(key2,pa)#找出關鍵字2的位置(從字1後面開始查找)

urlx=cont[pa:pt]#得到關鍵字1與關鍵字2之間的內容(即想要的數據)

print urlx

python 函數中怎麼實現static 變量

Python使用函數默認值實現函數靜態變量的方法,具體方法如下:

一、Python函數默認值

Python函數默認值的使用可以在函數調用時寫代碼提供方便,很多時候我們只要使用默認值就可以了。 所以函數默認值在python中用到的很多,尤其是在類中間,類的初始化函數中一幫都會用到默認值。 使用類時能夠方便的創建類,而不需要傳遞一堆參數。

只要在函數參數名後面加上 ”=defalut_value”,函數默認值就定義好了。有一個地方需要注意的是,有默認值的參數必須在函數參數列表的最後,不允許將沒有默認值的參數放在有默認值的參數後,因為如果你那樣定義的話,解釋器將不知道如何去傳遞參數。

先來看一段示例代碼:

def ask_ok(prompt, retries=4, complaint=’Yes or no, please!’):

while True:

ok = raw_input(prompt)

if ok in (‘y’, ‘ye’, ‘yes’): return True

if ok in (‘n’, ‘no’, ‘nop’, ‘nope’): return False

retries = retries – 1

if retries 0: raise IOError, ‘refusenik user’

print complaint

你調用上面的函數時,可以修改重試次數和輸出的提示語言,如果你比較懶得話,那麼什麼都不用改。

二、python使用函數默認值來實現函數靜態變量的功能

Python中是不支持靜態變量的,但是我們可以通過函數的默認值來實現靜態變量的功能。

當函數的默認值是內容是可變的類時,類的內容可變,而類的名字沒變。(相當於開闢的內存區域沒有變,而其中內容可以變化)。

這是因為python中函數的默認值只會被執行一次,(和靜態變量一樣,靜態變量初始化也是被執行一次。)這就是他們的共同點。

再來看下面的程序片段:

def f(a, L=[]):

L.append(a)

return L

print f(1)

print f(2)

print f(3)

print f(4,[‘x’])

print f(5)

其輸出結果是:

[1]

[1, 2]

[1, 2, 3]

[‘x’, 4]

[1, 2, 3, 5]

前面的好理解,為什麼最後 “print f(5)”的輸出是 “[1, 2, 3, 5]”呢?

這是因為 “print f(4,[‘x’])”時,默認變量並沒有被改變,因為默認變量的初始化只是被執行了一次(第一次使用默認值調用),初始化執行開闢的內存區(我們可以稱之為默認變量)沒有被改變,所以最後的輸出結果是“[1, 2, 3, 5]”。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/271776.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-16 19:23
下一篇 2024-12-16 19:23

相關推薦

  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29

發表回復

登錄後才能評論