Python Web编程概念梳理

Python Web编程概念梳理

主要讲解三个关键字

  1. 服务器
  2. WSGI
  3. 框架

前言

学编程有两种方式,一种是自上而下,一种是自下而上。

自上而下呢就是直接拿一些成熟的框架学习,看完一个简单的教程就能依葫芦画瓢作出一些小项目,比较容易获取成就感。Python Web服务端编程就是这样的,有许许多多成熟的框架,Django,flask,tornado,web.py.......学习一下这些框架的教程就能配合一个前端作出一些小网站。然后随着使用次数的增加,会发现很多的疑惑,去寻找答案,就慢慢的学习了底层的知识,感觉对框架的理解上了一个档次。

自下而上呢就是直接从底层开始学习,拿Python Web开发来说,可以从计算机网络,socket编程等等开始,但这一过程一般来说比较痛苦。

我呢就是自上而下的学习过程。我接触框架之前,掌握的只有python语法,基本的算法和数据结构等一系列学校里的专业课程。(计网当时还没学) 加入一个实验室后,学长就让我们用tornado框架做一个小网站,然后我就按照教程一点一点写,当然是写的很茫然,不知道为什么要引入这个,为什么引入那个,也不知道为什么别人就能给我发请求了。而且框架的那些条条框框根本记不住,每次写都得重新找教程,把一个大概的模板写好,然后开始写业务函数。

写过几个以后,居然觉得怎么这么简单,只要写几个业务函数,功能多就多写几个业务函数(年轻啊)。但是学着学着又觉得不对劲,用了很久就跟刚开始用一样,谈不上提升,因为写来写去都是在写业务函数。(如果有过来人指导我学习方向,一定轻松很多)

服务器

我之前一直不理解为什么需要apache,nginx这些服务器,也不知道他们的作用,因为我觉得python自己就有一些服务器的库,且tornado本身也有个服务器,所以在我之前的概念了,服务器就很模糊甚至不重要。

Python Web包括客户端和服务端,都是通过对系统提供的套接字(socket)编程来实现请求与响应,socket是操作系统提供的接口,但是各种编程语言都对它进行了封装成库,但是没有改变功能,只是是他更易使用。WEB服务器主要就是实现http协议,而http的底层协议是Tcp协议。

一个简单的TCP客户端和服务器

import socket

PORT = 7890

def server():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind('127.0.0.1', PORT)
    sock.listen(5)
    print('listening at port: ', PORT)
    while true:
        sc, sockname = sock.accept()
        data = sc.recv(4096)
        print('received data: ', data)
        sc.sendall(b'hello world')
        sc.close()

def client():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect('127.0.0.1', PORT)
    sock.sendall(b'hi, server')
    reply = sock.recv(4096)
    print('server said: ', reply)
    sock.close()

server通过bind()监听请求,一旦有请求就生成一个套接字与客户端连接,然后双方通过套接字发送信息。(明白大概意思就行,我也不会socket底层编程)

TCP协议是socket已经提供的,web服务器需要做的就是实现http协议以及如何提高服务器的效率,比如单线程,多线程,多进程,异步等等。而Python中有socket库,所以是可以用Python自己实现一个服务器的(只谈可操作性,我不会别人会-_-)。

那用Python写的http服务器与apache这些web服务器有什么区别呢?

apache这些服务器主要是返回静态内容的,我们自己编写的http服务器主要是返回一些动态内容。这里强调一下是主要,因为对于两种服务器来说两种内容都是可以支持的,不过是各有所长。所以都用或者只用一个都是可以的,这取决于不同的Web部署方案。但是apache这种服务器由于只要接受http请求并响应,所以在这方面做了很多优化,使其速度非常快,且更通用。

三种方案

  1. apache这类Web服务器只接受和响应静态请求,将动态请求转发给Python服务器。这样需要运行两个守护进程来监听请求

  2. apache接受全部请求,自己处理静态请求,动态请求调用CGI脚本执行后拿到结果返回。这样只有一个服务器

  3. 不使用apache这类服务器,直接使用Python服务器。

当然服务器的功能还有很多,比如缓存,负载,反向代理,安全等等,所以需要考虑很多方面来决定如何选择所要的服务器。

WSGI

WSGI的全称是Web Server Gateway Interface,即Web服务器网关接口。具体的来说,WSGI是一个规范,定义了Web服务器如何与Python应用程序进行交互,使得使用Python写的Web应用程序可以和Web服务器(包含上面两种)对接起来。WSGI一开始是在PEP-0333中定义的,最新版本是在Python的PEP-3333定义的。(不懂吧,那就继续看)

为什么要有WSGI呢?

一般来说后端是不需要编写服务器的,因为有很多现成的解决方案,所以只需要写一些应用程序来供调用。

目前最广泛的部署方案是:

首先,部署一个Web服务器专门用来处理HTTP协议层面相关的事情,比如如何在一个物理机上提供多个不同的Web服务(单IP多域名,单IP多端口等)这种事情。

然后,部署一个用各种语言编写(Java, PHP, Python, Ruby等)的应用程序,这个应用程序会从Web服务器上接收客户端的请求,处理完成后,再返回响应给Web服务器,最后由Web服务器返回给客户端。

由上一节内容可以知道,服务器有很多种,不同的服务器接口不同,那么采用这种方案,Web服务器与应用程序就需要知道如何交互,就出现了很多规范,最早的一个是CGI,然后有Java专用的Servlet规范以及Python专用的WSGI规范。定义规范就是为了定义统一的标准,提升程序的移植性。

在WSGI中定义了两个角色,Web服务器端称为server或者gateway,应用程序端称为application或者framework。server端接受用户请求后根据规范调用application端。这也是大多数框架里运行时都需要一个application的原因。

application对象定义形式

def app(environ, start_response):
    pass

environ参数是一个Python字典,存放与客户端相关的信息,start_response是一个可调用对象,接受两个必选参数和一个可选参数。

application一个简单的示例

def app(environ, start_response):
    host = environ.get('HTTP_HOST', '127.0.0.1')
    path = environ.get('PATH_INFO', '/')
    if ':' in host:
        host, port = host.split(':', 1)
    if '?' in path:
        path, query = path.split('?', 1)
    headers = [('Content-Type', 'text/plain; charset=utf-8')]
    if environ['REQUEST_METHOD'] != 'GET':
        start_response('501 Not Implemented', headers)
        yield b'501 Not Implemented'
    elif host != '127.0.0.1' or path != '/':
        start_response('404 Not Found', headers)
        yield b'404 Not Found'
    else:
        start_response('200 OK', headers)

框架

从上面那个app的示例代码可以看出,如果我们不使用Web框架,就需要自己根据environ的信息来作一系列的判断,而且这些判断是繁琐的,却意义不大的。

让框架帮我们做完这些苦力活,帮助我们过滤掉与服务不符的主机名,路径以及方法等没用的请求,我们就可以专心的处理业务函数。框架能帮我们将environ分析为一个对象,直接供我们调用,并帮我们返回除了响应体以外的一些http相关的信息。当然框架还可以实现很多其他东西,比如Django的admin等。

但是有一种框架比较特殊,那就是tornado这类支持协程或绿色线程的异步服务器,所以导致我在学tornado的时候没遇到过WSGI,但是看其他框架却经常出现这些词汇。

至于框架的选择,我给不出太多的意见。主流的就是Django和Flask,但遗憾的是在我什么都不懂的时候,实验室要求我们使用tornado框架。不是说tornado不好,但是tornado这种编程风格确实是新手不友好的,且文档,学习资料与Django比起来少了太多太多,之后我会换一个框架开始学习,Django和Flask中选择一个,因为这些社区环境昊,教程比较多,适合自学。

水平不高,如有错误请指出!谢谢!cfk0419@163.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容