python面向对象编程

1、面向对象编程

在Python中,全部数据类型均可以视为对象,固然也能够自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。html

面向对象的设计思想是抽象出Class,根据Class建立Instance。web

面向对象的抽象程度又比函数要高,由于一个Class既包含数据,又包含操做数据的方法。数据库

类和实例

定义以下:django

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

class后面紧接着是类名,即Student类名一般是大写开头的单词,紧接着是(object),表示该类是从哪一个类继承下来的,继承的概念咱们后面再讲,一般,若是没有合适的继承类,就使用object类,这是全部类最终都会继承的类。编程

建立实例是经过类名+()实现的:bart=Student()json

能够自由地给一个实例变量绑定属性。flask

和静态语言不一样,Python容许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不一样实例,但拥有的变量名称均可能不一样。浏览器

好比,给实例bart绑定一个name属性:ruby

>>> bart.name = 'Bart Simpson'
>>> bart.name
'Bart Simpson'

在建立实例的时候,能够将属性绑定,是经过特殊方法 __init__ (先后分别有两个下划线)。服务器

注意到__init__方法的第一个参数永远是self,表示建立的实例自己,所以,在__init__方法内部,就能够把各类属性绑定到self,由于self就指向建立的实例自己。

有了__init__方法,在建立实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不须要传,Python解释器本身会把实例变量传进去:

>>> bart = Student('Bart Simpson', 59)
>>> bart.name
'Bart Simpson'
>>> bart.score
59

数据封装

外部不直接访问类中的属性,而是经过类中的方法来间接访问。

class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print('%s: %s' % (self.name, self.score))

要定义一个方法,除了第一个参数是self外,其余和普通函数同样。要调用一个方法,只须要在实例变量上直接调用,除了self不用传递,其余参数正常传入。

这样一来,咱们从外部看Student类,就只须要知道,建立实例须要给出namescore,而如何打印,都是在Student类的内部定义的,这些数据和逻辑被“封装”起来了,调用很容易,但却不用知道内部实现的细节。

访问限制

 

2、网络编程

用Python进行网络编程,就是在Python程序自己这个进程内,链接别的服务器进程的通讯端口进行通讯。

TCP/IP协议

互联网协议包含了上百种协议标准,可是最重要的两个协议是TCP和IP协议,因此,你们把互联网的协议简称TCP/IP协议。

通讯的时候,双方必须知道对方的标识,比如发邮件必须知道对方的邮件地址。互联网上每一个计算机的惟一标识就是IP地址,相似123.123.123.123。若是一台计算机同时接入到两个或更多的网络,好比路由器,它就会有两个或多个IP地址,因此,IP地址对应的其实是计算机的网络接口,一般是网卡。

IP协议负责把数据从一台计算机经过网络发送到另外一台计算机。数据被分割成一小块一小块,而后经过IP包发送出去。因为互联网链路复杂,两台计算机之间常常有多条线路,所以,路由器就负责决定如何把一个IP包转发出去。IP包的特色是按块发送,途径多个路由,但不保证能到达,也不保证顺序到达。

TCP协议则是创建在IP协议之上的。TCP协议负责在两台计算机之间创建可靠链接,保证数据包按顺序到达。TCP协议会经过握手创建链接,而后,对每一个IP包编号,确保对方按顺序收到,若是包丢掉了,就自动重发。

许多经常使用的更高级的协议都是创建在TCP协议基础上的,好比用于浏览器的HTTP协议、发送邮件的SMTP协议等。

一个TCP报文除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。

端口有什么做用?在两台计算机通讯时,只发IP地址是不够的,由于同一台计算机上跑着多个网络程序。一个TCP报文来了以后,究竟是交给浏览器仍是QQ,就须要端口号来区分。每一个网络程序都向操做系统申请惟一的端口号,这样,两个进程在两台计算机之间创建网络链接就须要各自的IP地址和各自的端口号。

一个进程也可能同时与多个计算机创建连接,所以它会申请不少端口。

TCP编程

客户端

大多数链接都是可靠的TCP链接。建立TCP链接时,主动发起链接的叫客户端,被动响应链接的叫服务器。

举个例子,经过Socket向百度发请求

import socket

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.baidu.com',80))

# 发送数据:
s.send(b'GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n')

# 接收数据:
buffer = []
while True:
    # 每次最多接收1k字节:
    d = s.recv(1024)
    if d:
        buffer.append(d)
    else:
        break
data = b''.join(buffer)
# 关闭链接:
s.close()

header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))
# 把接收的数据写入文件:
with open('baidu.html', 'wb') as f:
    f.write(html)
View Code

解释:

建立Socket时,AF_INET指定使用IPv4协议,若是要用更先进的IPv6,就指定为AF_INET6SOCK_STREAM指定使用面向流的TCP协议

客户端要主动发起TCP链接,必须知道服务器的IP地址和端口号,参数是一个tuple

TCP链接建立的是双向通道,双方均可以同时给对方发数据。可是谁先发谁后发,怎么协调,要根据具体的协议来决定。例如,HTTP协议规定客户端必须先发请求给服务器,服务器收到后才发数据给客户端。

发送的文本格式必须符合HTTP标准,若是格式没问题,接下来就能够接收新浪服务器返回的数据了。

接收数据时,调用recv(max)方法,一次最多接收指定的字节数,所以,在一个while循环中反复接收,直到recv()返回空数据,表示接收完毕,退出循环。

接收完数据后,调用close()方法关闭Socket,这样,一次完整的网络通讯就结束了。接收到的数据包括HTTP头和网页自己,咱们只须要把HTTP头和网页分离一下,把HTTP头打印出来,网页内容保存到文件。

服务器 

服务器进程首先要绑定一个端口并监听来自其余客户端的链接。若是某个客户端链接过来了,服务器就与该客户端创建Socket链接,随后的通讯就靠这个Socket链接了。

因此,服务器会打开固定端口(好比80)监听,每来一个客户端链接,就建立该Socket链接。因为服务器会有大量来自客户端的链接,因此,服务器要可以区分一个Socket链接是和哪一个客户端绑定的。一个Socket依赖4项:服务器地址、服务器端口、客户端地址、客户端端口来惟一肯定一个Socket。

可是服务器还须要同时响应多个客户端的请求,因此,每一个链接都须要一个新的进程或者新的线程来处理,不然,服务器一次就只能服务一个客户端了

咱们来编写一个简单的服务器程序,它接收客户端链接,把客户端发过来的字符串加上Hello再发回去。

 服务端

import socket
import threading
import time

# 链接创建后,服务器首先发一条欢迎消息,而后等待客户端数据,并加上Hello再发送给客户端。若是客户端发送了exit字符串,就直接关闭链接。
def tcplink(sock, addr):
    print('Accept new connection from %s:%s...' % addr)
    sock.send(b'Welcome!')
    while True:
        data = sock.recv(1024)
        time.sleep(1)
        if not data or data.decode('utf-8') == 'exit':
            break
        sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
    sock.close()
    print('Connection from %s:%s closed.' % addr)


s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 请注意,小于1024的端口号必需要有管理员权限才能绑定
s.bind(('127.0.0.1',9999))
# 指定等待链接的最大数量
s.listen(5)
print('Waiting for connection...')
while True:
    # 接受一个新链接:
    sock, addr = s.accept()
    # 建立新线程来处理TCP链接:
    t = threading.Thread(target=tcplink, args=(sock, addr))
    t.start()
View Code

客户端

import  socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 创建链接:
s.connect(('127.0.0.1', 9999))
# 接收欢迎消息:
print(s.recv(1024).decode('utf-8'))
for data in [b'Michael', b'Tracy', b'Sarah']:
    # 发送数据:
    s.send(data)
    print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
View Code

须要打开两个命令行窗口,一个运行服务器程序,另外一个运行客户端程序,就能够看到效果了 。

须要注意的是,客户端程序运行完毕就退出了,而服务器程序会永远运行下去,必须按Ctrl+C退出程序。

 

3、Web开发

Python的诞生历史比Web还要早,因为Python是一种解释型的脚本语言,开发效率高,因此很是适合用来作Web开发。

Python有上百种Web开发框架,有不少成熟的模板技术,选择Python开发Web应用,不但开发效率高,并且运行速度快。

一个Web应用的本质就是:

  1. 浏览器发送一个HTTP请求;

  2. 服务器收到请求,生成一个HTML文档;

  3. 服务器把HTML文档做为HTTP响应的Body发送给浏览器;

  4. 浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。

最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。Apache、Nginx、Lighttpd等这些常见的静态服务器就是干这件事情的。

作法是底层代码由专门的服务器软件实现,咱们用Python专一于生成HTML文档。由于咱们不但愿接触到TCP链接、HTTP原始请求和响应格式,因此,须要一个统一的接口,让咱们专心用Python编写Web业务。

这个接口就是WSGI:Web Server Gateway Interface

WSGI

WSGI接口定义很是简单,它只要求Web开发者实现一个函数,就能够响应HTTP请求。咱们来看一个最简单的Web版本的“Hello, web!”:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']

上面的application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

  • environ:一个包含全部HTTP请求信息的dict对象;

  • start_response:一个发送HTTP响应的函数,只能调一次。

 函数的返回值b'<h1>Hello, web!</h1>'将做为HTTP响应的Body发送给浏览器。

有了WSGI,咱们关心的就是如何从environ这个dict对象拿到HTTP请求信息,而后构造HTML,经过start_response()发送Header,最后返回Body

整个application()函数自己没有涉及到任何解析HTTP的部分,也就是说,底层代码不须要咱们本身编写,咱们只负责在更高层次上考虑如何响应请求就能够了。

 

不过,等等,这个application()函数怎么调用?若是咱们本身调用,两个参数environstart_response咱们无法提供,返回的bytes也无法发给浏览器。

因此application()函数必须由WSGI服务器来调用。有不少符合WSGI规范的服务器,咱们能够挑选一个来用。可是如今,咱们只想尽快测试一下咱们编写的application()函数真的能够把HTML输出到浏览器,因此,要赶忙找一个最简单的WSGI服务器,把咱们的Web应用程序跑起来。

好消息是Python内置了一个WSGI服务器,这个模块叫wsgiref,它是用纯Python编写的WSGI服务器的参考实现。所谓“参考实现”是指该实现彻底符合WSGI标准,可是不考虑任何运行效率,仅供开发和测试使用。

 hello.py

def application(environ,start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    #return [b'<h1>Hello, web!</h1>']

    #改造一下
    body = '<h1>Hello, %s!</h1>' % (environ['PATH_INFO'][1:] or 'web')
    return [body.encode('utf-8')]
View Code

server.py

# 从WSgiref模板导入
from wsgiref.simple_server import make_server
#  导入咱们编写的application函数
from hello import application

# 建立一个服务器,IP地址为空,端口是8000,处理函数是application:
httpd = make_server('', 8000, application)
print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()
View Code

执行server.py,而后打开浏览器:http://localhost:8000/  或者 http://localhost:8000/huy

不管多么复杂的Web应用程序,入口都是一个WSGI处理函数HTTP请求的全部输入信息均可以经过environ得到,HTTP响应的输出均可以经过start_response()加上函数返回值做为Body

复杂的Web应用程序,光靠一个WSGI函数来处理仍是太底层了,咱们须要在WSGI之上再抽象出Web框架,进一步简化Web开发。

使用Web框架

用Python开发一个Web框架十分容易,因此Python有上百个开源的Web框架。这里咱们先不讨论各类Web框架的优缺点,直接选择一个比较流行的Web框架——Flask来使用。

 先用pip安装Flask: pip install flask

而后写一个xxx.py,处理3个URL,分别是:

  • GET /:首页,返回Home

  • GET /signin:登陆页,显示登陆表单;

  • POST /signin:处理登陆表单,显示登陆结果。

注意噢,同一个URL/signin分别有GET和POST两种请求,映射到两个处理函数中。

Flask经过Python的装饰器在内部自动地把URL和函数给关联起来,

from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/',methods=['GET','POST'])
def home():
    return '<h1>home page</h1>'

@app.route('/signin',methods=['GET'])
def signin_form():
    return '''<form action="/signin" method="post">
              <p><input name="username"></p>
              <p><input name="password" type="password"></p>
              <p><button type="submit">Sign In</button></p>
              </form>'''

@app.route('/signin', methods=['POST'])
def signin():
    # 须要从request对象读取表单内容:
    if request.form['username']=='admin' and request.form['password']=='password':
        return '<h3>Hello, admin!</h3>'
    return '<h3>Bad username or password.</h3>'

if __name__ == '__main__':
    app.run()
View Code

Flask自带的Server在端口5000上监听,输入首页地址http://localhost:5000/

再输入 http://localhost:5000/signin

输入预设的用户名admin和口令password,登陆成功。。输个错误密码试试。。

实际的Web App应该拿到用户名和口令后,去数据库查询再比对,来判断用户是否能登陆成功。

除了Flask,常见的Python Web框架还有:

  • Django:全能型Web框架;

  • web.py:一个小巧的Web框架;

  • Bottle:和Flask相似的Web框架;

  • Tornado:Facebook的开源异步Web框架。

固然了,由于开发Python的Web框架也不是什么难事,咱们后面也会讲到开发Web框架的内容。

有了Web框架,咱们在编写Web应用时,注意力就从WSGI处理函数转移到URL+对应的处理函数,这样,编写Web App就更加简单了

在编写URL处理函数时,除了配置URL外,从HTTP请求拿到用户数据也是很是重要的。Web框架都提供了本身的API来实现这些功能。Flask经过request.form['name']来获取表单的内容。

使用模板

使用模板,咱们须要预先准备一个HTML文档,这个HTML文档不是普通的HTML,而是嵌入了一些变量和指令,而后,根据咱们传入的数据,替换后,获得最终的HTML,发送给用户:

mvc-seq

这就是传说中的MVC:Model-View-Controller,中文名“模型-视图-控制器”

Python处理URL的函数就是C:Controller,Controller负责业务逻辑,好比检查用户名是否存在,取出用户信息等等;

包含变量{{ name }}的模板就是V:View,View负责显示逻辑,经过简单地替换一些变量,View最终输出的就是用户看到的HTML。

MVC中的Model在哪?Model是用来传给View的,这样View在替换变量的时候,就能够从Model中取出相应的数据。

上面的例子中,Model就是一个dict{ 'name': 'Michael' }

只是由于Python支持关键字参数,不少Web框架容许传入关键字参数,而后,在框架内部组装出一个dict做为Model

如今,咱们把上次直接输出字符串做为HTML的例子用高端大气上档次的MVC模式改写一下:

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def home():
    return render_template('home.html')

@app.route('/signin', methods=['GET'])
def signin_form():
    return render_template('form.html')

@app.route('/signin', methods=['POST'])
def signin():
    username = request.form['username']
    password = request.form['password']
    if username=='admin' and password=='password':
        return render_template('signin-ok.html', username=username)
    return render_template('form.html', message='Bad username or password', username=username)

if __name__ == '__main__':
    app.run()
View Code

Flask经过render_template()函数来实现模板的渲染。和Web框架相似,Python的模板也有不少种。Flask默认支持的模板是jinja2,因此咱们先直接安装jinja2:

$ pip install jinja2 

而后,开始编写jinja2模板:

home.html
用来显示首页的模板:

<html>
<head>
  <title>Home</title>
</head>
<body>
  <h1 style="font-style:italic">Home</h1>
</body>
</html>
form.html
用来显示登陆表单的模板:

<html>
<head>
  <title>Please Sign In</title>
</head>
<body>
  {% if message %}
  <p style="color:red">{{ message }}</p>
  {% endif %}
  <form action="/signin" method="post">
    <legend>Please sign in:</legend>
    <p><input name="username" placeholder="Username" value="{{ username }}"></p>
    <p><input name="password" placeholder="Password" type="password"></p>
    <p><button type="submit">Sign In</button></p>
  </form>
</body>
</html>
signin-ok.html
登陆成功的模板:

<html>
<head>
  <title>Welcome, {{ username }}</title>
</head>
<body>
  <p>Welcome, {{ username }}!</p>
</body>
</html>
View Code

登陆失败的模板呢?咱们在form.html中加了一点条件判断,把form.html重用为登陆失败的模板。

最后,必定要把模板放到正确的templates目录下,templatesapp.py在同级目录下:

mvc-dir

启动:http://localhost:5000/  再输入 http://localhost:5000/signin

在Jinja2模板中,咱们{{ name }}表示一个须要替换的变量。不少时候,还须要循环、条件判断等指令语句,在Jinja2中,用{% ... %}表示指令

好比循环输出页码:

{% for i in page_list %}
    <a href="/page/{{ i }}">{{ i }}</a> {% endfor %} 

若是page_list是一个list:[1, 2, 3, 4, 5],上面的模板将输出5个超连接。

除了Jinja2,常见的模板还有:

  • Mako:用<% ... %>${xxx}的一个模板;

  • Cheetah:也是用<% ... %>${xxx}的一个模板;

  • Django:Django是一站式框架,内置一个用{% ... %}{{ xxx }}的模板。

 

4、异步IO

CPU的速度远远快于磁盘、网络等IO。在一个线程中,CPU执行代码的速度极快,然而,一旦遇到IO操做,如读写文件、发送网络数据时,就须要等待IO操做完成,才能继续进行下一步操做。这种状况称为同步IO

由于一个IO操做就阻塞了当前线程,致使其余代码没法执行,因此咱们必须使用多线程或者多进程来并发执行代码,为多个用户服务。每一个用户都会分配一个线程,若是遇到IO致使线程被挂起,其余用户的线程不受影响。

多线程和多进程的模型虽然解决了并发问题,可是系统不能无上限地增长线程。因为系统切换线程的开销也很大,因此,一旦线程数量过多,CPU的时间就花在线程切换上了,真正运行代码的时间就少了,结果致使性能严重降低。

因为咱们要解决的问题是CPU高速执行能力和IO设备的龟速严重不匹配,多线程和多进程只是解决这一问题的一种方法。

另外一种解决IO问题的方法是异步IO当代码须要执行一个耗时的IO操做时,它只发出IO指令,并不等待IO结果,而后就去执行其余代码了。一段时间后,当IO返回结果时,再通知CPU进行处理

 异步IO模型须要一个消息循环,在消息循环中,主线程不断地重复“读取消息-处理消息”这一过程

协程

 又称微线程,纤程。英文名Coroutine。

子程序,或者称为函数,在全部语言中都是层级调用,好比A调用B,B在执行过程当中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。因此子程序调用是经过栈实现的,一个线程就是执行一个子程序。

子程序调用老是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不一样。

协程看上去也是子程序,但执行过程当中,在子程序内部可中断,而后转而执行别的子程序,在适当的时候再返回来接着执行(不是函数调用,有点相似CPU的中断)

特色

协程的特色在因而一个线程执行,那和多线程比,协程有何优点?

最大的优点就是协程极高的执行效率。由于子程序切换不是线程切换,而是由程序自身控制,所以,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优点就越明显。

第二大优点就是不须要多线程的锁机制,由于只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只须要判断状态就行了,因此执行效率比多线程高不少。

由于协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可得到极高的性能。

Python对协程的支持是经过generator(生成器)实现的。

 注:若是一个函数定义中包含yield关键字,那么这个函数就再也不是一个普通函数,而是一个generator。。遇到语句返回,再次执行时从上次返回的语句处继续执行。yieldyield

在generator中,咱们不但能够经过for循环来迭代,还能够不断调用next()函数获取yield语句返回的下一个值。

可是Python的yield不但能够返回一个值,它还能够接收调用者发出的参数。

asyncio异步io

asyncio的编程模型就是一个消息循环。咱们从asyncio模块中直接获取一个EventLoop的引用,而后把须要执行的协程扔到EventLoop中执行,就实现了异步IO

asyncio实现Hello world代码以下:

import asyncio

@asyncio.coroutine
def hello():
    print("Hello world!")
    # 异步调用asyncio.sleep(1):
    r = yield from asyncio.sleep(1)
    print("Hello again!")

# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()
View Code

@asyncio.coroutine把一个generator标记为coroutine类型(协程),而后,咱们就把这个coroutine扔到EventLoop中执行。

hello()会首先打印出Hello world!,而后,yield from语法可让咱们方便地调用另外一个generator因为asyncio.sleep()也是一个coroutine,因此线程不会等待asyncio.sleep(),而是直接中断并执行下一个消息循环。当asyncio.sleep()返回时,线程就能够从yield from拿到返回值(此处是None),而后接着执行下一行语句。

asyncio.sleep(1)当作是一个耗时1秒的IO操做,在此期间,主线程并未等待,而是去执行EventLoop中其余能够执行的coroutine了,所以能够实现并发执行。

 

asyncio的异步网络链接来获取sina、sohu和163的网站首页:

import asyncio

@asyncio.coroutine
def wget(host):
    print('wget %s...' % host)
    connect = asyncio.open_connection(host, 80)
    reader, writer = yield from connect
    header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
    writer.write(header.encode('utf-8'))
    yield from writer.drain()
    while True:
        line = yield from reader.readline()
        if line == b'\r\n':
            break
        print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
    # Ignore the body, close the socket
    writer.close()

loop = asyncio.get_event_loop()
tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
View Code

asyncio提供了完善的异步IO支持;

异步操做须要在coroutine中经过yield from完成

多个coroutine能够封装成一组Task而后并发执行

async/await

asyncio提供的@asyncio.coroutine能够把一个generator标记为coroutine类型,而后在coroutine内部用yield from调用另外一个coroutine实现异步操做。

为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法asyncawait,可让coroutine的代码更简洁易读

请注意,asyncawait是针对coroutine的新语法,要使用新的语法,只须要作两步简单的替换:

  1. @asyncio.coroutine替换为async
  2. yield from替换为await
async def hello():
    print("Hello world!")
    r = await asyncio.sleep(1)
    print("Hello again!")
View Code

aiohttp

asyncio能够实现单线程并发IO操做。若是仅用在客户端,发挥的威力不大。若是把asyncio用在服务器端,例如Web服务器,因为HTTP链接就是IO操做,所以能够用单线程+coroutine实现多用户的高并发支持

asyncio实现了TCP、UDP、SSL等协议,aiohttp则是基于asyncio实现的HTTP框架

咱们先安装aiohttp

pip install aiohttp

而后编写一个HTTP服务器,分别处理如下URL:

  • / 

  • /about

代码以下:

import asyncio
from aiohttp import web

routes = web.RouteTableDef()

@routes.get('/')
async def index(request):
    await asyncio.sleep(2)
    return web.json_response({
        'name': 'index'
    })


@routes.get('/about')
async def about(request):
    await asyncio.sleep(0.5)
    return web.Response(text="<h1>about us</h1>")


def init():
    app = web.Application()
    app.add_routes(routes)
    web.run_app(app)

init()
View Code

运行后输入:http://localhost:8080/

相关文章
相关标签/搜索