欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

python

How to install pip with Python 3? 安装 python3 有大用

普通分类: 

期末总结

终于到了期末总结的时刻了!

经过一段时间的学习,相信你对Python已经初步掌握。一开始,可能觉得Python上手很容易,可是越往后学,会越困难,有的时候,发现理解不了代码,这时,不妨停下来思考一下,先把概念搞清楚,代码自然就明白了。

Python非常适合初学者用来进入计算机编程领域。Python属于非常高级的语言,掌握了这门高级语言,就对计算机编程的核心思想——抽象有了初步理解。如果希望继续深入学习计算机编程,可以学习Java、C、JavaScript、Lisp等不同类型的语言,只有多掌握不同领域的语言,有比较才更有收获。

普通分类: 

FAQ

常见问题

本节列出常见的一些问题。

如何获取当前路径

当前路径可以用'.'表示,再用os.path.abspath()将其转换为绝对路径:

# -*- coding:utf-8 -*-
# test.py

import os

print(os.path.abspath('.'))

运行结果:

$ python3 test.py 
/Users/michael/workspace/testing

如何获取当前模块的文件名

可以通过特殊变量__file__获取:

# -*- coding:utf-8 -*-
# test.py

print(__file__)

输出:

普通分类: 

Day 16 - 编写移动App

网站部署上线后,还缺点啥呢?

在移动互联网浪潮席卷而来的今天,一个网站没有上线移动App,出门根本不好意思跟人打招呼。

所以,awesome-python3-webapp必须得有一个移动App版本!

开发iPhone版本

我们首先来看看如何开发iPhone App。前置条件:一台Mac电脑,安装XCode和最新的iOS SDK。

在使用MVVM编写前端页面时,我们就能感受到,用REST API封装网站后台的功能,不但能清晰地分离前端页面和后台逻辑,现在这个好处更加明显,移动App也可以通过REST API从后端拿到数据。

我们来设计一个简化版的iPhone App,包含两个屏幕:列出最新日志和阅读日志的详细内容:

只需要调用API:/api/blogs

普通分类: 

Day 15 - 部署Web App

作为一个合格的开发者,在本地环境下完成开发还远远不够,我们需要把Web App部署到远程服务器上,这样,广大用户才能访问到网站。

很多做开发的同学把部署这件事情看成是运维同学的工作,这种看法是完全错误的。首先,最近流行DevOps理念,就是说,开发和运维要变成一个整体。其次,运维的难度,其实跟开发质量有很大的关系。代码写得垃圾,运维再好也架不住天天挂掉。最后,DevOps理念需要把运维、监控等功能融入到开发中。你想服务器升级时不中断用户服务?那就得在开发时考虑到这一点。

下面,我们就来把awesome-python3-webapp部署到Linux服务器。

普通分类: 

Day 14 - 完成Web App

在Web App框架和基本流程跑通后,剩下的工作全部是体力活了:在Debug开发模式下完成后端所有API、前端所有页面。我们需要做的事情包括:

把当前用户绑定到request上,并对URL/manage/进行拦截,检查当前用户是否是管理员身份:

普通分类: 

Day 13 - 提升开发效率

现在,我们已经把一个Web App的框架完全搭建好了,从后端的API到前端的MVVM,流程已经跑通了。

在继续工作前,注意到每次修改Python代码,都必须在命令行先Ctrl-C停止服务器,再重启,改动才能生效。

在开发阶段,每天都要修改、保存几十次代码,每次保存都手动来这么一下非常麻烦,严重地降低了我们的开发效率。有没有办法让服务器检测到代码修改后自动重新加载呢?

Django的开发环境在Debug模式下就可以做到自动重新加载,如果我们编写的服务器也能实现这个功能,就能大大提升开发效率。

可惜的是,Django没把这个功能独立出来,不用Django就享受不到,怎么办?

其实Python本身提供了重新载入模块的功能,但不是所有模块都能被重新载入。另一种思路是检测www目录下的代码改动,一旦有改动,就自动重启服务器。

按照这个思路,我们可以编写一个辅助程序pymonitor.py,让它启动wsgiapp.py,并时刻监控www目录下的代码改动,有改动时,先把当前wsgiapp.py进程杀掉,再重启,就完成了服务器进程的自动重启。

普通分类: 

Day 12 - 编写日志列表页

MVVM模式不但可用于Form表单,在复杂的管理页面中也能大显身手。例如,分页显示Blog的功能,我们先把后端代码写出来:

apis.py中定义一个Page类用于存储分页信息:

普通分类: 

Day 11 - 编写日志创建页

在Web开发中,后端代码写起来其实是相当容易的。

例如,我们编写一个REST API,用于创建一个Blog:

普通分类: 

Day 10 - 用户注册和登录

用户管理是绝大部分Web网站都需要解决的问题。用户管理涉及到用户注册和登录。

用户注册相对简单,我们可以先通过API把用户注册这个功能实现了:

普通分类: 

Day 9 - 编写API

自从Roy Fielding博士在2000年他的博士论文中提出REST(Representational State Transfer)风格的软件架构模式后,REST就基本上迅速取代了复杂而笨重的SOAP,成为Web API的标准了。

什么是Web API呢?

如果我们想要获取一篇Blog,输入http://localhost:9000/blog/123,就可以看到id为123的Blog页面,但这个结果是HTML页面,它同时混合包含了Blog的数据和Blog的展示两个部分。对于用户来说,阅读起来没有问题,但是,如果机器读取,就很难从HTML中解析出Blog的数据。

如果一个URL返回的不是HTML,而是机器能直接解析的数据,这个URL就可以看成是一个Web API。比如,读取http://localhost:9000/api/blogs/123,如果能直接返回Blog的数据,那么机器就可以直接读取。

普通分类: 

Day 8 - 构建前端

虽然我们跑通了一个最简单的MVC,但是页面效果肯定不会让人满意。

对于复杂的HTML前端页面来说,我们需要一套基础的CSS框架来完成页面布局和基本样式。另外,jQuery作为操作DOM的JavaScript库也必不可少。

从零开始写CSS不如直接从一个已有的功能完善的CSS框架开始。有很多CSS框架可供选择。我们这次选择uikit这个强大的CSS框架。它具备完善的响应式布局,漂亮的UI,以及丰富的HTML组件,让我们能轻松设计出美观而简洁的页面。

可以从uikit首页下载打包的资源文件。

所有的静态资源文件我们统一放到www/static目录下,并按照类别归类:

普通分类: 

Day 7 - 编写MVC

现在,ORM框架、Web框架和配置都已就绪,我们可以开始编写一个最简单的MVC,把它们全部启动起来。

通过Web框架的@get和ORM框架的Model支持,可以很容易地编写一个处理首页URL的函数:

@get('/')
def index(request):
    users = yield from User.findAll()
    return {
        '__template__': 'test.html',
        'users': users
    }

'__template__'指定的模板文件是test.html,其他参数是传递给模板的数据,所以我们在模板的根目录templates下创建test.html

普通分类: 

Day 6 - 编写配置文件

有了Web框架和ORM框架,我们就可以开始装配App了。

通常,一个Web App在运行时都需要读取配置文件,比如数据库的用户名、口令等,在不同的环境中运行时,Web App可以通过读取不同的配置文件来获得正确的配置。

由于Python本身语法简单,完全可以直接用Python源代码来实现配置,而不需要再解析一个单独的.properties或者.yaml等配置文件。

默认的配置文件应该完全符合本地开发环境,这样,无需任何设置,就可以立刻启动服务器。

我们把默认的配置文件命名为config_default.py

普通分类: 

Day 5 - 编写Web框架

在正式开始Web开发前,我们需要编写一个Web框架。

aiohttp已经是一个Web框架了,为什么我们还需要自己封装一个?

原因是从使用者的角度来说,aiohttp相对比较底层,编写一个URL的处理函数需要这么几步:

第一步,编写一个用@asyncio.coroutine装饰的函数:

@asyncio.coroutine
def handle_url_xxx(request):
    pass

第二步,传入的参数需要自己从request中获取:

url_param = request.match_info['key']
query_params = parse_qs(request.query_string)

最后,需要自己构造Response对象:

普通分类: 

Day 4 - 编写Model

有了ORM,我们就可以把Web App需要的3个表用Model表示出来:

普通分类: 

Day 3 - 编写ORM

在一个Web App中,所有数据,包括用户信息、发布的日志、评论等,都存储在数据库中。在awesome-python3-webapp中,我们选择MySQL作为数据库。

Web App里面有很多地方都要访问数据库。访问数据库需要创建数据库连接、游标对象,然后执行SQL语句,最后处理异常,清理资源。这些访问数据库的代码如果分散到各个函数中,势必无法维护,也不利于代码复用。

所以,我们要首先把常用的SELECT、INSERT、UPDATE和DELETE操作用函数封装起来。

由于Web框架使用了基于asyncio的aiohttp,这是基于协程的异步模型。在协程中,不能调用普通的同步IO操作,因为所有用户都是由一个线程服务的,协程的执行速度必须非常快,才能处理大量用户的请求。而耗时的IO操作不能在协程中以同步的方式调用,否则,等待一个IO操作时,系统无法响应任何其他用户。

这就是异步编程的一个原则:一旦决定使用异步,则系统每一层都必须是异步,“开弓没有回头箭”。

幸运的是aiomysql为MySQL数据库提供了异步IO的驱动。

普通分类: 

Day 2 - 编写Web App骨架

由于我们的Web App建立在asyncio的基础上,因此用aiohttp写一个基本的app.py

普通分类: 

Day 1 - 搭建开发环境

搭建开发环境

首先,确认系统安装的Python版本是3.5.x:

$ python3 --version
Python 3.5.1

然后,用pip安装开发Web App需要的第三方库:

异步框架aiohttp:

$pip3 install aiohttp

前端模板引擎jinja2:

$ pip3 install jinja2

MySQL 5.x数据库,从官方网站下载并安装,安装完毕后,请务必牢记root口令。为避免遗忘口令,建议直接把root口令设置为password

MySQL的Python异步驱动程序aiomysql:

$ pip3 install aiomysql

项目结构

选择一个工作目录,然后,我们建立如下的目录结构:

普通分类: 

实战

看完了教程,是不是有这么一种感觉:看的时候觉得很简单,照着教程敲代码也没啥大问题。

于是准备开始独立写代码,就发现不知道从哪开始下手了。

这种情况是完全正常的。好比学写作文,学的时候觉得简单,写的时候就无从下笔了。

虽然这个教程是面向小白的零基础Python教程,但是我们的目标不是学到60分,而是学到90分。

所以,用Python写一个真正的Web App吧!

目标

我们设定的实战目标是一个Blog网站,包含日志、用户和评论3大部分。

很多童鞋会想,这是不是太简单了?

比如webpy.org上就提供了一个Blog的例子,目测也就100行代码。

但是,这样的页面:

你拿得出手么?

普通分类: 

aiohttp

asyncio可以实现单线程并发IO操作。如果仅用在客户端,发挥的威力不大。如果把asyncio用在服务器端,例如Web服务器,由于HTTP连接就是IO操作,因此可以用单线程+coroutine实现多用户的高并发支持。

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

我们先安装aiohttp

pip install aiohttp

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

  • / - 首页返回b'<h1>Index</h1>'

  • /hello/{name} - 根据URL参数返回文本hello, %s!

代码如下:

普通分类: 

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

让我们对比一下上一节的代码:

普通分类: 

asyncio

asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。

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

asyncio实现Hello world代码如下:

普通分类: 

协程

在学习异步IO模型前,我们先来了解协程。

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

协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用。

子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。

所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。

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

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。比如子程序A、B:

def A():
    print('1')
    print('2')
    print('3')

def B():
    print('x')
    print('y')
    print('z')

假设由协程执行,在执行A的过程中,可以随时中断,去执行B,B也可能在执行过程中中断再去执行A,结果可能是:

普通分类: 

异步IO

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

在IO操作的过程中,当前线程被挂起,而其他需要CPU执行的代码就无法被当前线程执行了。

因为一个IO操作就阻塞了当前线程,导致其他代码无法执行,所以我们必须使用多线程或者多进程来并发执行代码,为多个用户服务。每个用户都会分配一个线程,如果遇到IO导致线程被挂起,其他用户的线程不受影响。

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

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

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

普通分类: 

使用模板

Web框架把我们从WSGI中拯救出来了。现在,我们只需要不断地编写函数,带上URL,就可以继续Web App的开发了。

但是,Web App不仅仅是处理逻辑,展示给用户的页面也非常重要。在函数中返回一个包含HTML的字符串,简单的页面还可以,但是,想想新浪首页的6000多行的HTML,你确信能在Python的字符串中正确地写出来么?反正我是做不到。

俗话说得好,不懂前端的Python工程师不是好的产品经理。有Web开发经验的同学都明白,Web App最复杂的部分就在HTML页面。HTML不仅要正确,还要通过CSS美化,再加上复杂的JavaScript脚本来实现各种交互和动画效果。总之,生成HTML页面的难度很大。

由于在Python代码里拼字符串是不现实的,所以,模板技术出现了。

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

普通分类: 

使用Web框架

了解了WSGI框架,我们发现:其实一个Web App,就是写一个WSGI的处理函数,针对每个HTTP请求进行响应。

但是如何处理HTTP请求不是问题,问题是如何处理100个不同的URL。

每一个URL可以对应GET和POST请求,当然还有PUT、DELETE等请求,但是我们通常只考虑最常见的GET和POST请求。

一个最简单的想法是从environ变量里取出HTTP请求的信息,然后逐个判断:

普通分类: 

WSGI接口

了解了HTTP协议和HTML文档,我们其实就明白了一个Web应用的本质就是:

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

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

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

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

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

如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。

正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。

普通分类: 

HTML简介

网页就是HTML?这么理解大概没错。因为网页中不但包含文字,还有图片、视频、Flash小游戏,有复杂的排版、动画效果,所以,HTML定义了一套语法规则,来告诉浏览器如何把一个丰富多彩的页面显示出来。

HTML长什么样?上次我们看了新浪首页的HTML源码,如果仔细数数,竟然有6000多行!

所以,学HTML,就不要指望从新浪入手了。我们来看看最简单的HTML长什么样:

<html>
<head>
  <title>Hello</title>
</head>
<body>
  <h1>Hello, world!</h1>
</body>
</html>

可以用文本编辑器编写HTML,然后保存为hello.html,双击或者把文件拖到浏览器中,就可以看到效果:

普通分类: 

HTTP协议简介

在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来。而浏览器和服务器之间的传输协议是HTTP,所以:

  • HTML是一种用来定义网页的文本,会HTML,就可以编写网页;

  • HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。

在举例子之前,我们需要安装Google的Chrome浏览器

为什么要使用Chrome浏览器而不是IE呢?因为IE实在是太慢了,并且,IE对于开发和调试Web应用程序完全是一点用也没有。

我们需要在浏览器很方便地调试我们的Web应用,而Chrome提供了一套完整地调试工具,非常适合Web开发。

安装好Chrome浏览器后,打开Chrome,在菜单中选择“视图”,“开发者”,“开发者工具”,就可以显示开发者工具:

普通分类: 

页面

Subscribe to RSS - python