温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python中的知识点有哪些

发布时间:2021-10-18 16:00:37 来源:亿速云 阅读:126 作者:小新 栏目:编程语言

这篇文章主要为大家展示了“Python中的知识点有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python中的知识点有哪些”这篇文章吧。


WEB发展历程

最早的时候,WEB就是一些静态文件。由开发人员通过编辑器直接编辑生成静态的HTML页面,如果要修改WEB页面的内容或布局,就得编辑这些静态的HTML文件。早期的时候就是这么来玩的,是不是让人着实不爽?

由于静态WEB页面无法与用户进行交互(提交表单等操作)。为了解决这一问题,人们开发出了一种称为CGI(Common Gateway Interface)的技术,使用 C/C++ 编写。

由于WEB应用的特点是频繁更新,用低级语言非常不适合高效地开发。而脚本语言(JSP、PHP)由于开发效率高,与HTML结合紧密,因此,迅速取代了CGI模式。JSP使用Java编写脚本,而PHP则是开源的脚本语言。

最早的动态页面是CGI实现的,CGI是怎么工作的?当请求某个地址的时候,http服务器会启动一个外部程序,并且把外部程序的输出返回给用户。CGI规范了http和外部程序的通信方式。

  • 输入:通过环境变量

  • 输出:通过标准输出

CGI的缺点:

  1. 并发模式是多进程

  2. 进程由http服务器管理

基于CGI以上的缺点,由此衍生出了FastCGI技术,把进程管理交给其他服务来处理。http服务器把http协议转化成fastcgi协议,通过socket发送给FastCGI守护进程。这样并发模型变得多种多样,进程管理由FastCGI实现,单一原则。

另一个分支就是由cgi发展的wsgi技术。接下来就看看wsgi。

Web框架的主要关键点:

  1. 路由

  2. Request解析

  3. Response封装

WSGI

Web服务器网关接口(WSGI)是Python Web应用程序框架和Web服务器之间标准接口的规范。

在Python Web应用程序的早期,由于没有统一的标准,将Web应用程序框架连接到Web服务器是不容易的。Python Web应用程序是用于工作的,具体是通过运用现有的CGI、FastCGI或mod_python(Apache)标准之一。这意味着在一个Web服务器上工作的应用程序可能无法在另一个Web服务器上工作。换言之,统一的应用程序与Web服务器之间的互操作性没有了。

WSGI通过在服务器和Web应用框架之间指定一个简单但统一的接口来解决这个问题,从而允许移植Web应用程序。

WSGI指定了两个方面:服务器(或网关)端,以及应用程序或框架端。WSGI请求得到了以下处理:

  • 服务器端执行应用程序,给应用程序提供一个环境和一个回调函数。

  • 应用程序处理请求,并使用所提供的回调函数返回响应给服务器。

流程如下:
Python中的知识点有哪些

wsgi两部分组成:容器,应用。也可以把容器称为网关或服务器。容器实现了协议转换,由http协议到wsgi协议的转换;应用用来处理业务逻辑。

容器和应用怎么通信呢?FastCGI通过socket;wsgi的容器和应用通过函数调用进行通信。什么情况下可以通过函数调用实现通信?同一进程内可以实现函数调用,wsgi的容器和应用是运行在同一进程之中。

常用的wsgi容器:gunicorn,uWSGI。

一个可工作的HelloWorld

说了这么多,还是看个简单的例子吧,看看wsgi是如何工作的。接下来实现一个helloworld的程序。

wsgi application应该是一个callable对象。函数是可调用的,如果一个类有__call__方法,也是可调用的。

wsgi函数的书写有一定的要求,它的函数签名一般如下,比较固定:

def application(environ, start_response):
    '''
    # 函数传入的参数是有规定的:
    # environ:environ变量是从服务器传递到应用程序的环境变量的字典,如请求内容等;
    # 由公共网关接口(CGI)规范定义。WSGI在其规范中规定了一些环境变量受托者
    # start_response:一个可调用对象,其提供一个从服务器端到应用程序端的回调,从而开启服务器端的
    # 响应处理。它必须有两个位置参数。第一个应该是具有整型状态吗的状态字符串,第二个是一个(header_name, header_value)列表,其是描述HTTP头响应的元组。
    '''
    pass

上述函数传入的参数是有规定的:

  1. environenviron变量是从服务器传递到应用程序的环境变量的字典,如请求内容等;由公共网关接口(CGI)规范定义。WSGI在其规范中规定了一些环境变量受托者

  2. start_response:一个可调用对象,其提供一个从服务器端到应用程序端的回调,从而开启服务器端的响应处理。它必须有两个位置参数。第一个应该是具有整型状态吗的状态字符串,第二个是一个(header_name, header_value)列表,其是描述HTTP头响应的元组。

要了解更多的WSGI规范,可以看看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

通常在开发的时候,使用wsgiref就行了,如果在生产中,可以使用第三方的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有同名的

执行结果如下:

{'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上可能就会执行上述代码。
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中的知识点有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI