溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中的知識點有哪些

發(fā)布時間:2021-10-18 16:00:37 來源:億速云 閱讀:147 作者:小新 欄目:編程語言

這篇文章主要為大家展示了“Python中的知識點有哪些”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Python中的知識點有哪些”這篇文章吧。


WEB發(fā)展歷程

最早的時候,WEB就是一些靜態(tài)文件。由開發(fā)人員通過編輯器直接編輯生成靜態(tài)的HTML頁面,如果要修改WEB頁面的內容或布局,就得編輯這些靜態(tài)的HTML文件。早期的時候就是這么來玩的,是不是讓人著實不爽?

由于靜態(tài)WEB頁面無法與用戶進行交互(提交表單等操作)。為了解決這一問題,人們開發(fā)出了一種稱為CGI(Common Gateway Interface)的技術,使用 C/C++ 編寫。

由于WEB應用的特點是頻繁更新,用低級語言非常不適合高效地開發(fā)。而腳本語言(JSP、PHP)由于開發(fā)效率高,與HTML結合緊密,因此,迅速取代了CGI模式。JSP使用Java編寫腳本,而PHP則是開源的腳本語言。

最早的動態(tài)頁面是CGI實現(xiàn)的,CGI是怎么工作的?當請求某個地址的時候,http服務器會啟動一個外部程序,并且把外部程序的輸出返回給用戶。CGI規(guī)范了http和外部程序的通信方式。

  • 輸入:通過環(huán)境變量

  • 輸出:通過標準輸出

CGI的缺點:

  1. 并發(fā)模式是多進程

  2. 進程由http服務器管理

基于CGI以上的缺點,由此衍生出了FastCGI技術,把進程管理交給其他服務來處理。http服務器把http協(xié)議轉化成fastcgi協(xié)議,通過socket發(fā)送給FastCGI守護進程。這樣并發(fā)模型變得多種多樣,進程管理由FastCGI實現(xiàn),單一原則。

另一個分支就是由cgi發(fā)展的wsgi技術。接下來就看看wsgi。

Web框架的主要關鍵點:

  1. 路由

  2. Request解析

  3. Response封裝

WSGI

Web服務器網(wǎng)關接口(WSGI)是Python Web應用程序框架和Web服務器之間標準接口的規(guī)范。

在Python Web應用程序的早期,由于沒有統(tǒng)一的標準,將Web應用程序框架連接到Web服務器是不容易的。Python Web應用程序是用于工作的,具體是通過運用現(xiàn)有的CGI、FastCGI或mod_python(Apache)標準之一。這意味著在一個Web服務器上工作的應用程序可能無法在另一個Web服務器上工作。換言之,統(tǒng)一的應用程序與Web服務器之間的互操作性沒有了。

WSGI通過在服務器和Web應用框架之間指定一個簡單但統(tǒng)一的接口來解決這個問題,從而允許移植Web應用程序。

WSGI指定了兩個方面:服務器(或網(wǎng)關)端,以及應用程序或框架端。WSGI請求得到了以下處理:

  • 服務器端執(zhí)行應用程序,給應用程序提供一個環(huán)境和一個回調函數(shù)。

  • 應用程序處理請求,并使用所提供的回調函數(shù)返回響應給服務器。

流程如下:
Python中的知識點有哪些

wsgi兩部分組成:容器,應用。也可以把容器稱為網(wǎng)關或服務器。容器實現(xiàn)了協(xié)議轉換,由http協(xié)議到wsgi協(xié)議的轉換;應用用來處理業(yè)務邏輯。

容器和應用怎么通信呢?FastCGI通過socket;wsgi的容器和應用通過函數(shù)調用進行通信。什么情況下可以通過函數(shù)調用實現(xiàn)通信?同一進程內可以實現(xiàn)函數(shù)調用,wsgi的容器和應用是運行在同一進程之中。

常用的wsgi容器:gunicorn,uWSGI。

一個可工作的HelloWorld

說了這么多,還是看個簡單的例子吧,看看wsgi是如何工作的。接下來實現(xiàn)一個helloworld的程序。

wsgi application應該是一個callable對象。函數(shù)是可調用的,如果一個類有__call__方法,也是可調用的。

wsgi函數(shù)的書寫有一定的要求,它的函數(shù)簽名一般如下,比較固定:

def application(environ, start_response):
    '''
    # 函數(shù)傳入的參數(shù)是有規(guī)定的:
    # environ:environ變量是從服務器傳遞到應用程序的環(huán)境變量的字典,如請求內容等;
    # 由公共網(wǎng)關接口(CGI)規(guī)范定義。WSGI在其規(guī)范中規(guī)定了一些環(huán)境變量受托者
    # start_response:一個可調用對象,其提供一個從服務器端到應用程序端的回調,從而開啟服務器端的
    # 響應處理。它必須有兩個位置參數(shù)。第一個應該是具有整型狀態(tài)嗎的狀態(tài)字符串,第二個是一個(header_name, header_value)列表,其是描述HTTP頭響應的元組。
    '''
    pass

上述函數(shù)傳入的參數(shù)是有規(guī)定的:

  1. environenviron變量是從服務器傳遞到應用程序的環(huán)境變量的字典,如請求內容等;由公共網(wǎng)關接口(CGI)規(guī)范定義。WSGI在其規(guī)范中規(guī)定了一些環(huán)境變量受托者

  2. start_response:一個可調用對象,其提供一個從服務器端到應用程序端的回調,從而開啟服務器端的響應處理。它必須有兩個位置參數(shù)。第一個應該是具有整型狀態(tài)嗎的狀態(tài)字符串,第二個是一個(header_name, header_value)列表,其是描述HTTP頭響應的元組。

要了解更多的WSGI規(guī)范,可以看看PEP 3333提案。

開始寫:

def application(environ, start_response):
    body = 'hello world'
    status = '200 OK'
    headers = [
        ('content-type', 'text/plain'),
        ('content-length', str(len(body)))
    ]
    start_response(status, headers)
    return [body.encode()]

# 以上代碼只有應用,沒有容器;
if __name__ == '__main__':
    # 引入wsgi容器
    from wsgiref.simple_server import make_server

    server = make_server('0.0.0.0', 8000, application)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()

運行以上代碼,并在瀏覽器上進行訪問:

[lavenliu@VM_113_230_centos 12-web]$ python wsgi01.py 
183.192.25.121 - - [13/Oct/2018 18:48:08] "GET / HTTP/1.1" 200 11
183.192.25.121 - - [13/Oct/2018 18:48:09] "GET /favicon.ico HTTP/1.1" 200 11
183.192.25.121 - - [13/Oct/2018 18:48:09] "GET /favicon.ico HTTP/1.1" 200 11

也可以通過curl命令行工具進行訪問:

curl -XPOST http://127.0.0.1:8000 -d '{"a": 1}'

接下來使用gunicorn容器來運行上述代碼:

# 首先安裝gunicorn
pip install gunicorn

# 接著運行wsgi01.py的application應用
[lavenliu@VM_113_230_centos 12-web]$ gunicorn -b 0.0.0.0 wsgi01:application
[2018-10-13 18:55:38 +0800] [18359] [INFO] Starting gunicorn 19.6.0
[2018-10-13 18:55:38 +0800] [18359] [INFO] Listening at: http://0.0.0.0:8000 (18359)
[2018-10-13 18:55:38 +0800] [18359] [INFO] Using worker: sync
[2018-10-13 18:55:38 +0800] [18397] [INFO] Booting worker with pid: 18397

通常在開發(fā)的時候,使用wsgiref就行了,如果在生產(chǎn)中,可以使用第三方的wsgi容器。

上面的代碼中,如果想看environ中的內容,可以在上述代碼中添加如下的代碼:

for k, v in environ.items():
    print('{} => {}'.format(k, v))

# 完整的代碼如下:
# coding: utf-8

def application(environ, start_response):
    for k, v in environ.items():
        print('{} => {}'.format(k, v))
    body = 'hello world'
    status = '200 OK'
    headers = [
        ('content-type', 'text/plain'),
        ('content-length', str(len(body)))
    ]
    start_response(status, headers)
    return [body.encode()]

# 以上只有應用代碼,沒有容器

if __name__ == '__main__':

    from wsgiref.simple_server import make_server
    server = make_server('0.0.0.0', 8000, application)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()

如果再次運行代碼,會有如下的輸出:

wsgi.input => <gunicorn.http.body.Body object at 0x7fe20286c198>
HTTP_ACCEPT_ENCODING => gzip, deflate
HTTP_ACCEPT_LANGUAGE => zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
SERVER_PORT => 8000
RAW_URI => /
REMOTE_PORT => 16252
HTTP_USER_AGENT => Mozilla/5.0 (Windows NT 6.3; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
wsgi.file_wrapper => <class 'gunicorn.http.wsgi.FileWrapper'>
REMOTE_ADDR => 183.192.25.121
wsgi.version => (1, 0)
wsgi.url_scheme => http
HTTP_HOST => 115.159.125.96:8000
wsgi.multithread => False
HTTP_ACCEPT => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
wsgi.multiprocess => False
QUERY_STRING => 
SERVER_SOFTWARE => gunicorn/19.6.0
SERVER_PROTOCOL => HTTP/1.1
PATH_INFO => /
HTTP_CONNECTION => keep-alive
REQUEST_METHOD => GET
wsgi.run_once => False
wsgi.errors => <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7fe20286c1d0>
SERVER_NAME => 0.0.0.0
HTTP_CACHE_CONTROL => max-age=0
SCRIPT_NAME => 
gunicorn.socket => <socket.socket fd=10, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('10.105.113.230', 8000), raddr=('183.192.25.121', 16252)>

environ中有一個QUERY_STRING的key,我們可以打印該信息:

[lavenliu@VM_113_230_centos 12-web]$ cat wsgi01.py 
# coding: utf-8

def application(environ, start_response):
    print(environ.get('QUERY_STRING'))

    body = 'hello world'
    status = '200 OK'
    headers = [
        ('content-type', 'text/plain'),
        ('content-length', str(len(body)))
    ]
    start_response(status, headers)
    return [body.encode()]

# 以上只有應用代碼,沒有容器
if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server = make_server('0.0.0.0', 8000, application)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()

在瀏覽器的URL地址欄里輸入:

http://115.159.125.96:8000?name=lavenliu&age=25

運行效果如下:

[lavenliu@VM_113_230_centos 12-web]$ gunicorn -b 0.0.0.0 wsgi01:application
[2018-10-13 19:15:36 +0800] [20609] [INFO] Starting gunicorn 19.6.0
[2018-10-13 19:15:36 +0800] [20609] [INFO] Listening at: http://0.0.0.0:8000 (20609)
[2018-10-13 19:15:36 +0800] [20609] [INFO] Using worker: sync
[2018-10-13 19:15:36 +0800] [20647] [INFO] Booting worker with pid: 20647
name=lavenliu&age=25 # 獲得的來自客戶端的輸入

上面的輸出中,

name=lavenliu&age=25 # 獲得的來自客戶端的輸入

接下來就是解析來自客戶端的輸入,解析這件事也不是很困難,不過有標準庫來處理這個解析的工作,引入標準庫:

from urllib.parse import parse_qs
from html import escape

parse_qs('name=lavenliu&age=25')
# 返回的value是列表,因為有可能key有同名的

執(zhí)行結果如下:

{'age': ['25'], 'name': ['lavenliu']}

接下來的代碼如下:

[lavenliu@VM_113_230_centos 12-web]$ cat wsgi02.py 
# coding: utf-8
from urllib.parse import parse_qs
from html import escape

def application(environ, start_response):
    params = parse_qs(environ.get('QUERY_STRING'))
    name = params.get('name', ['anon'])[0]
    body = 'hello {}'.format(name)  # 如果用戶在瀏覽器里輸入非法的東東時,可能會有問題
    status = '200 OK'
    headers = [
        ('content-type', 'text/html'),
        ('content-length', str(len(body)))
    ]
    start_response(status, headers)
    return [body.encode()]

# 以上只有應用代碼,沒有容器
if __name__ == '__main__':
    from wsgiref.simple_server import make_server

    server = make_server('0.0.0.0', 8001, application)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()

如果用戶在瀏覽器這樣輸入,就有可能有問題:

http://115.159.125.96:8001?name=<script type='text/javascript'>alert('f**k it')</script>
# chrome瀏覽器則沒有問題,它會檢測到這個輸入有問題;如果在IE6上可能就會執(zhí)行上述代碼。
Navigated to http://115.159.125.96:8001/?%3Cscript%20type=%27text/javascript%27%3Ealert(%27f**k%20it%27)%3C/script%3E
?name=<script type='text/javascript'>alert('f**k it')</script>:1 The XSS Auditor refused to execute a script in 'http://115.159.125.96:8001/?name=%3Cscript%20type=%27text/javascript%27%3Ealert(%27f**k%20it%27)%3C/script%3E' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.

Navigated to http://115.159.125.96:8001/?name=%3Cscript%20type=%27text/javascript%27%3Ealert(%27f**k%20it%27)%3C/script%3E

# 在火狐瀏覽器就能通過,不會報錯
# IE11版本則沒有這個問題

以上是“Python中的知識點有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI