(转)如何理解Nginx、uWSGI和Flask之间的关系?

󰃭 2017-04-09

转载自 如何理解Nginx、uWSGI和Flask之间的关系? 总括来说,客户端从发送一个 HTTP 请求到 Flask 处理请求,分别经过了 web 服务器层,WSGI层,web框架层,这三个层次。不同的层次其作用也不同,下面简要介绍各层的作用。 图1:web服务器,web框架与 WSGI 的三层关系 Web服务器层 对于传统的客户端 - 服务器架构,其请求的处理过程是,客户端向服务器发送请求,服务器接收请求并处理请求,然后给客户端返回响应。在这个过程中,服务器的作用是: 接收请求 处理请求 返回响应 Web服务器是一类特殊的服务器,其作用是主要是接收 HTTP 请求并返回响应。提起 web服务器大家都不会陌生,常见的 web服务器有 Nginx,Apache,IIS等。在上图1的三层结构中,web服务器是最先接收用户请求的,并将响应结果返回给用户。 Web框架层 Web框架的作用主要是方便我们开发 web应用程序,HTTP请求的动态数据就是由 web框架层来提供的。常见的 web框架有Flask,Django等,我们以 Flask 框架为例子,展示 web框架的作用: from flask import Flask app = Flask(__name__) @app.route('/hello') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run(host='0.0.0.0', port=8080) 以上简单的几行代码,就创建了一个 web应用程序对象 app。 app 监听机器所有 ip 的 8080 端口,接受用户的请求连接。我们知道,HTTP 协议使用 URL 来定位资源,上面的程序会将路径 /hello 的请求交由 hello_world 方法处理, hello_world 返回 ‘Hello World!

Continue reading 


python学习笔记:第七章 用户输入和while循环

󰃭 2017-04-09

python学习笔记:第七章 用户输入和while循环 input() message = input("Tell me something, and I will repeat it back to you:") print(message) name = input("Please enter your name: ") print("Hello," + name + "!") prompt = "If you tell us who you are, we can personalize the messages you see." prompt += "\nWhat is your first name?" name = input(prompt) print("\nHello," + name + "!") 使用input()来获取数值输入 height = input("How tall are you, in inches?") height = int(height) if height >= 36: print("\nYou're tall enough to ride!

Continue reading 


test flow

󰃭 2017-04-07

st=>start: Start e=>end op=>operation: My Operation con=>condition: Yes or No? st->op->cond cond(yes)->e cond(no)->op

Continue reading 


python学习笔记:第六章 字典

󰃭 2017-04-06

python学习笔记:第六章 字典 一个简单的字典 alien_0 = {'color': 'green', 'points': 5} print(alien_0['color']) print(alien_0['points']) 值赋给变量 new_points = alien_0['points'] print ("You just earned " + str(new_points) + " points!") 已有字典中增加键-值 alien_0['x_position'] = 0 alien_0['y_positon'] = 25 print(alien_0) 空字典增加键-值 alien_0 = {} alien_0['color'] = 'green' alien_0['points'] = 5 print(alien_0) 修改字典中的键-值 alien_0 = {'color': 'green'} print("The alien is " + alien_0['color'] + ".") alien_0['color'] = 'yellow' print("The alien is now " + alien_0['color'] + ".") 外星人来了 位置+速度—移动至新位置。

Continue reading 


实例讲解 Scrapy 爬虫 (一)

󰃭 2017-04-05

scrapy 简介 scrapy 是使用 python 语言开发的网络爬虫框架。 具有下面几个特点: 设计简单,用户只需要简单定义数据提取规则,让 scrapy 完成抓取的工作,即可获取数据。 提供丰富的插件扩展机制 开源,100% 用 python 编写(基于 twisted 框架) 官方文档比较详细 本系列包含的主题 scrapy 介绍,基本知识 基本网页抓取(spider item pipeline)开发 downloader middlewares 开发 extensions(扩展)开发 调试 scrapy scrapy 开发中的问题合集(跟随项目更新) 基础知识 所有的资料方法都来自: 官方文档 scrapy 源代码 python 3.4.2 scrapy 主要组件 scrapy engine, 控制整个爬虫的运行,请求调度,spider调用,下载调用,信号事件触发 spider(蜘蛛), 用来解析页面的类,解析后创建新的请求,或者创建数据结果集合 scheduler(调度器), 负责管理请求(来自 spider),存入队列,执行时返回给 scrapy引擎 Downloader(下载器),抓取页面并返回结果给 spider Item pipeline(item管道), 处理网页中抽取的数据结果,进行清洗,校验,存储等操作 Downloader middlewares(下载器中间件),下载器与 spider 之间的勾子,可以对请求和响应的数据进行操作 extensions(扩展),在 scrapy 启动时初始化,提供增强的辅助功能 上面是主要用到的一些组件,还有 spider middlerwares 等没包含在内 scrapy 运行机制 引擎调用蜘蛛获取第一个要抓取的 url, 存入调度器 引擎从调度器获取请求 url(上面放入的 url), 引擎传递请求 -> 下载中间件 -> 下载器 下载器下载页面,响应结果 -> 下载中间件 -> 引擎 引擎把响应结果交给蜘蛛处理 蜘蛛解析响应,创建结果 Item 和新的请求 结果 item 交给 item 管道处理 新的请求存入调度器,重复上面的操作 环境安装 $ virtualenv -p python3 /project/scrapyenv $ source /project/scrapyenv/bin/active $ pip install scrapy scrapy 基本命令 $ scrapy --help Scrapy 1.

Continue reading 


python学习笔记: 第五章 if语句

󰃭 2017-04-05

python学习笔记: 第五章 if语句 示例 cars = ['audi', 'bmw', 'subaru', 'toyota'] for car in cars: if car == 'bmw': print(car.upper()) else: print(car.title()) 条件测试 car = 'Audi' print(car == 'audi') print(car.lower() == 'audi') print(car) 相等判定 requested_topping = 'mushrooms' if requested_topping != 'anchovies': print("Hold the anchovies!") 检查特定值是否在列表中,如果不在则加入列表 requested_topping = ['mushrooms', 'onions', 'pineapple'] one_topping = 'tomato' if one_topping not in requested_topping: print(one_topping.title() + "is not here!") requested_topping.append(one_topping) print(requested_topping) 输入并判断是否在列表中: if-else语句 requested_topping = ['mushrooms', 'onions', 'pineapple'] print("请输入一种requsted_topping:\n>>") topping = input() if topping in requested_topping: print("Hi,%s is here!

Continue reading 


python 爬虫之Requests 模块简介

󰃭 2017-04-04

安装 一行命令即可完成安装 pip install requests 请求 Get 请求 使用requests 发起GET请求的方式如下 不带参数的请求 import requests if __name__ == '__main__': resp = requests.get('http://www.baidu.com') print(resp) 结果如下 <Response [200]> 得到的是一个响应状态吗为200的response 对象, 这个对象我们后面解释 以上就获取到了一个不带参数的请求 带参数的请求 当get请求格式如下时, 是怎么发起请求的呢 https://www.baidu.com/s?wd=test 如下 params = {'wd': 'test'} resp = requests.get('https://www.baidu.com/s', params=params) print(resp) # <Response [200]> print(resp.url) # https://www.baidu.com/s?wd=test 也可以得到一个200的response对象 POST 请求 如果是 post 请求, 如何发起请求呢 一般的post 请求, 比如模仿 html的form 表单, 向服务器 post 表单数据, 格式如下即可 params = {'name': 'tony', 'age': '22'} resp = requests.

Continue reading 


python学习笔记: 第四章 操作列表

󰃭 2017-04-03

学习笔记 第四章 打印列表中的所有元素 magicians = ['alice', 'david', 'carolina'] for magician in magicians: print(magician) print(magician.title() + ", that was a great trick!") print("I can't wait to see your next trick, " + magician.title() + ".\n") print("Thank you, everyone. That was a great magic show!") 使用range()生成list for value in range(1,5): print(value) 数字列表的生成 numbers = list(range(1,6)) print(numbers) 偶数列表 even_numbers = list(range(2,11,2)) print(even_numbers) 空列表填充数字 squares = [] for value in range(1,11): square = value ** 2 squares.

Continue reading 


学习笔记: Python编程:从入门到实践 第四章 操作列表

󰃭 2017-04-03

打印列表中所有元素 magicians = ['alice', 'david', 'carolina'] for magician in magicians: print(magician) print(magician.title() + ", that was a great trick!") print("I can't wait to see your next trick, " + magician.title() + ".\n") print("Thank you, everyone. That was a great magic show!") 使用range()生成list for value in range(1,5): print(value) 数字列表的生成 numbers = list(range(1,6)) print(numbers) 偶数列表 even_numbers = list(range(2,11,2)) print(even_numbers) 空列表填充数字 squares = [] for value in range(1,11): square = value ** 2 squares.

Continue reading 


荒野的学习笔记: Python编程:从入门到实践 第四章 操作列表

󰃭 2017-04-03

荒野的学习笔记: Python编程:从入门到实践 第四章 操作列表 打印列表中所有元素 magicians = ['alice', 'david', 'carolina'] for magician in magicians: print(magician) print(magician.title() + ", that was a great trick!") print("I can't wait to see your next trick, " + magician.title() + ".\n") print("Thank you, everyone. That was a great magic show!") 使用range()生成list for value in range(1,5): print(value) 数字列表的生成 numbers = list(range(1,6)) print(numbers) 偶数列表 even_numbers = list(range(2,11,2)) print(even_numbers) 空列表填充数字 squares = [] for value in range(1,11): square = value ** 2 squares.

Continue reading 


列表命令1

󰃭 2017-04-02

#定义一个moto列表,并读出 motocycles = [‘honda’, ‘yamaha’, ‘suzuki’] print(motocycles) motocycles[0] = ‘ducati’ print(motocycles) #增加list motocycles.append(‘kasadi’) print(motocycles) #插入 motocycles.insert(0,‘aiya’) print(motocycles) #不再使用,del del motcycles(0) #print(motocycles) #还需使用,用pop first_owned = motocycles.pop(0) #print(‘The first motocycle I owned was a ’ + first_owned.title() + ‘.’) #根据值删除元素 motocycles.remove(‘kasadi’) #print(motocycles) #排序 print(motocycles) #永久变换顺序 motocycles.sort() #print(motocycles) #按照字母相反的顺序 motocycles.sort(reverse = True) print(motocycles) #暂时变换顺序 print(sorted(motocycles)) print(motocycles) #列表倒序 motocycles.reverse() print(motocycles) #长度 print(len(motocycles))

Continue reading 


中文print对齐

󰃭 2017-03-23

中文print对齐 在中英文混合的过程中,经常令我们困惑的是\t起不到预期的作用,那我们怎么去处理他呢? 实际上中文的占位为全角,相对于英文的半角来说,通常会是两倍的长度。基于此,一种解决方案是计算出字符串中的中文数,将为中文预留的空格去掉,这样我们就可以做到print对齐了。 比如说,这样一句话:我爱hiphop,给定打印长度为20。直接计算的话会在这句话后面加上(20-len)=12个空格。而实际上,中文占用两个字符,我们需要把给中文的字符去掉,那么就是(20-len-len_ch)=10个空格。 注意:这个方案中需要预留足够的占位距离 以下为具体实现: #coding=utf8 import re lst1 = ["1up", "无政府主义者食谱"] lst2 = ["额外生命", "召唤炸弹"] def singleton(cls): instances = {} def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] return getinstance @singleton class ChineseDetected(object): _re = None def __init__(self): self._re = re.compile('[\u4e00-\u9fa5]+') def get_count(self, s): chinese_list = self._re.findall(s) count = 0 for c_item in chinese_list: count += len(c_item) return count def printItemList(ilt, ilt2): len_list = [5, 20, 35] fmt_template = "{:%d}\t{:%d}\t{:%d}" def make_fmt(idx): return fmt_template%(len_list[0], len_list[1]-cd.

Continue reading 


(译)Python关键字yield的解释(stackoverflow)

󰃭 2017-03-21

转载自 @PyZh 已得到译者授权 ========================================== (译)Python关键字yield的解释(stackoverflow) :译者: hit9 :原文: http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained :译者注: 这是stackoverflow上一个很热的帖子,这里是投票最高的一个答案 .. Contents:: 提问者的问题 Python关键字yield的作用是什么?用来干什么的? 比如,我正在试图理解下面的代码:: def node._get_child_candidates(self, distance, min_dist, max_dist): if self._leftchild and distance - max_dist < self._median: yield self._leftchild if self._rightchild and distance + max_dist >= self._median: yield self._rightchild 下面的是调用:: result, candidates = list(), [self] while candidates: node = candidates.pop() distance = node._get_dist(obj) if distance <= max_dist and distance >= min_dist: result.extend(node._values) candidates.extend(node._get_child_candidates(distance, min_dist, max_dist)) return result 当调用 _get_child_candidates 的时候发生了什么?返回了一个列表?返回了一个元素?被重复调用了么? 什么时候这个调用结束呢?

Continue reading 


twisted 开发(2)-- Deferreds 组件

󰃭 2017-03-19

Deferreds 异步回调序列 Deferred 本质上是一个回调函数的集合,twisted 提供了对函数延迟调用的机制。 在 twisted 内部,使用 Deferred 对象管理回调序列。当异步请求结果返回时,使用 Deferred 对象调用回调序列中的函数。 这里通过几个例子来了解 Deferreds 使用的方式和工作的原理 from twisted.internet import reactor, defer def getDummyData(x): """ 创建一个 Deferred 对象,并返回这个对象 """ d = defer.Deferred() # 2 秒钟后执行 Deferred 回调函数序列,把 x * 3 作为参数传递给回调序列中的第一个函数 # reactor.callLater 是一个定时延迟调用的方法 reactor.callLater(2, d.callback, x * 3) return d def printData(result): """ 打印结果 """ print result d = getDummyData(3) # 添加回调函数到回调函数序列中 d.addCallback(printData) # 4 秒钟后停止 reactor 循环(退出进程) reactor.callLater(4, reactor.stop) # 开始 Twisted reactor 事件循环 reactor.

Continue reading 


twisted 开发(1)-- twisted 框架介绍

󰃭 2017-03-16

异步非阻塞框架 twisted 是一个事件驱动的网络开发框架,使用 python 开发。 twisted 框架编写的服务器有几个基本的元素: 应用程序对象(application):管理应用程序资源的对象,一个应用程序可以管理多个service对象。 服务(service),服务对象启动监听的端口, 协议工厂(factory):当客户端连接到服务器时,用来创建协议对象。 协议(protocol):每个协议对象对应一个网络连接。协议类处理网络协议(如http,ftp,自定义协议等) twisted 框架内部运行依赖的元素: reactor:异步事件的主要循环处理类,负责监控事件,调用注册的回调函数提供服务。(在linux上主要使用epoll/select来实现) defer: 异步回调序列,当序列被执行的时候,顺序执行注册的回调函数。 官方的一个例子 实现一个 echo server,创建文件 echoServ.py #!/usr/bin/env python # coding: utf-8 from twisted.internet.protocol import Protocol from twisted.internet.protocol import Factory from twisted.internet.endpoints import TCP4ServerEndpoint from twisted.internet import reactor class Echo(Protocol): ''' 协议类实现用户的服务协议,例如 http,ftp,ssh 等 ''' def __init__(self, factory): self.factory = factory def connectionMade(self): ''' 连接建立时被回调的方法 ''' self.factory.numProtocols = self.factory.numProtocols + 1 self.transport.write("Welcome! There are currently %d open connections.

Continue reading 


python 之 collections 模块简介使用

󰃭 2017-03-16

前言 python 内置的数据类型有 int/str/list/tuple/set/dict, 除此之外, python 的collections 模块又帮我们扩展了一些数据类型和表示形式 以下简介 OrderDict python 默认的字典存的是hash 结构, 字典的每个键值对之间是没有顺序之分的, 如下 In [8]: user_info = dict([('name', 'tony'), ('age', 26), ('sex', 'man')]) In [9]: print(user_info) {'sex': 'man', 'name': 'tony', 'age': 26} collections下的OrderDict提供了对有序字典的支持 In [22]: user_info = OrderedDict([('name', 'tony'), ('age', 26), ('sex', 'man')]) In [23]: print(user_info) OrderedDict([('name', 'tony'), ('age', 26), ('sex', 'man')]) 其他操作方式和普通的字典使用一样 namedtuple 正如这个模块名称, 命名了的元组 其可以为元组的每个元素命名, 实现通过命名的方式访问元组内容 如下 In [8]: resp = namedtuple('resp', ['value', 'error']) In [9]: r = resp(True, None) In [10]: r.

Continue reading 


windows下学习 Python 编程的一些基本知识

󰃭 2017-03-16

环境变量 操作系统环境变量 在操作系统中用来设置系统运行环境的参数,如: 变量名称 含义 TEMP 临时文件夹位置 WINDIR 操作系统文件夹位置 HOMEPATH 用户主目录的路径 PATH 可执行文件的搜索路径 (很重要) DATE 当前日期 访问操作系统环境变量有如下方法: 以下知识对于 windows 使用命令控制台查看 控制台访问,打开 windows 控制台,输入 echo %PATH% C:\User\kk> echo %PATH% C:\dev\python\Python35\Scripts\;C:\dev\python\Python35\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;c:\tools\aria2; 通过系统面板访问 操作系统环境变量作用 环境变量一般是给整个系统的程序使用的,也可以定义程序自己使用的环境变量 这里主要说下 PATH 环境变量,windows 下可执行文件的搜索路径 例如: 当系统要运行程序时候,没有使用程序的完整路径时,按照下面规则查找程序 系统当前路井下查找程序 操作系统使用 PATH 变量表示的路径查找程序,找到了就运行程序 注意: 在控制台执行 python,就是按照上面的规则查找,如果在 PATH 里面找不到就报错 有不少人刚开始学习 python 编程时,会遇到这个问题,就是因为安装时没有把 python 的路径设置到 PATH 里面 Python 进程环境 Python 在运行时如果需要导入第三方模块,也会有一定的查找规则,通过下面的方法查看路径查找的顺序 import sys print(sys.path) ['', 'C:\\dev\\python\\Python35\\Scripts\\ipython.exe', 'c:\\dev\\python\\python35\\python35.zip', 'c:\\dev\\python\\python35\\DLLs', 'c:\\dev\\python\\python35\\lib', 'c:\\dev\\python\\python35', 'c:\\dev\\python\\python35\\lib\\site-packages', 'c:\\dev\\python\\python35\\lib\\site-packages\\IPython\\extensions'] 程序与进程 程序本身是一个可执行文件,操作系统可以加载运行 进程是程序被系统加载执行起来的单元,操作系统为它分配内存,cpu等资源,调度它执行程序逻辑 当前路径 在操作系统中所有的文件和文件夹本身就是一颗目录树,所以在任何时刻你都会处于某一个目录下, 当你在桌面环境中时,默认在你的用户目录下

Continue reading 


python 之 文件读写

󰃭 2017-03-14

原创作品: 首发u3v3, 转载请保留 地址: https://www.u3v3.com/ar/1289 作者ID: Yi_Zhi_Yu 首发日期: 2017.3.4 前言 一直想总结一下 python 的文件相关的操作, 今天终于来了 python 内置的文件处理函数足以应付常见的文件处理, 以下分场景介绍使用方式 获取文件句柄 通过程序读写文件, 需要通过文件句柄, python 下的文件句柄获取通过open 函数 fh = open('/path/to/file', 'w') open的第一个参数是文件路径, 第二个参数是表示打开的文件句柄能够进行操作的权限模式, 常用的有以下几种 w: 打开文件, 清空文件内容重新写入 a: 打开文件, 向文件末尾追加内容 x: 打开一个新的文件, 进行写入, 如果文件存在, 抛出一个异常FileExistsError r: 只读模式打开文件 t: 文本模式 b: 二进制模式 上班部分表示的是文件句柄的操作模式, 下半部分表示操作的文件内容模式 默认是只读 + 文本模式, 即r+t, 如下 fh = open('/path/to/file', 'r+t') 写入文件 我们来尝试写入一行数据到某个文件中 写入一行数据到文件中 数据如下 Yi_Zhu_Yu, man 把这个写入文件 users.txt 中 fh = open('/tmp/users.txt', 'w+t') fh.

Continue reading 


Python常见技巧

󰃭 2017-03-14

内容摘自于下面两篇文章 30 Python Language Features and Tricks You May Not Know About 30 Essential Python Tips and Tricks for Programmers Python学习群:278529278 (欢迎交流) 前言 本篇是摘取的是一些基于python语言本身的语法糖和技巧,无论从可读性和方便的角度都很有帮助。 1 分拆 >>> a, b, c = 1, 2, 3 >>> a, b, c (1, 2, 3) >>> a, b, c = [1, 2, 3] >>> a, b, c (1, 2, 3) >>> a, b, c = (2 * i + 1 for i in range(3)) >>> a, b, c (1, 3, 5) >>> a, (b, c), d = [1, (2, 3), 4] >>> a 1 >>> b 2 >>> c 3 >>> d 4 2 变量交换 >>> a, b = 1, 2 >>> a, b = b, a >>> a, b (2, 1) 3 负索引 >>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> a[-1] 10 >>> a[-3] 8 4 逆向步长切片 >>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> a[::-1] [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] >>> a[::-2] [10, 8, 6, 4, 2, 0] 5 迭代数组下标和元素 >>> a = ['Hello', 'world', '!

Continue reading 


Tornado学习序篇(I/O多路复用)

󰃭 2017-03-11

原创作品:首发u3v3, 转载请保留 地址:https://www.u3v3.com/ar/1283 作者ID:noomrevils 首发日期:2017.3.11 Python学习群:278529278 (欢迎交流) 前言 在上篇文章利用Python实现简单HTTP代理验证 我们使用Bottle框架实现了一个乞丐版的代理验证服务页面,但是Bottle并不适合放在生产环境下去应对大量的验证请求。我们需要一个性能更强劲的服务来支持高并发。在文章结尾有提到了tornado,aiohttp这两个异步Web框架。aiohttp这个框架还在发展阶段,而tornado已经被应用很多对性能有要求的场景中,并且有着良好的表现,因此后续将重点学习和掌握这个框架,tornado和 Django, Flask这些同步的web框架比起来,是另一种实现思路。其中最大的特色就是它的IO事件循环。为了能够更好的理解框架本身的机制,我们先来熟悉底层的原理,这里我不会介绍太多计算机术语,会有更多生活中的例子帮大家熟悉基本的概念和流程。 阻塞/非阻塞 我们先来看这样一对概念,阻塞/非阻塞 在下面一张图中,管道的两端分别是进程和数据,我们可以先把进程想象成工厂里的工人,数据是他要加工处理的配件,配件需要通过传送带到达他手边。 当这个工人一直在传送带前面等待着配件过来,无法抽身去做别的事情,这时这个工人就被阻塞在了这里。这种等待-就绪-执行的流程很符合人的认知习惯,但是也显的呆板,效率不足。 现在有三个传送带,需要这个工人处理,传送带上的数据并不一定同时到达,之前阻塞模型就不再适用。我们的工人怎么才能处理现在这种情况呢?聪明的工人想出了一个办法,他不在一条传送带前傻等,他开始在不同的传送带之间来回走动,检查那个传送带上有需要处理的配件。在传送带上配件间隔不断的出现的情况下,工人处理的很快,效率也很多,但是当传送带上没有配件,并且传送带的数量开始增多的时候,他觉得这么来回走,一直在做无用功。 上面的模型,工人已经是一种非阻塞的状态,通过忙轮询,他似乎可以处理多条处理线,但是效率是极端的不稳定,浪费了不少时间。 人都是喜欢偷懒的,但是光偷懒不讲效率是要被找谈话的,于是工人就在厂房里装一个监控。他自己不在传送带前来回转了,他坐在监视前打着盹,开开小差。 监视器连着摄像头和厂房进货口的一个传感器,它一旦收到进货口传感器信号,就会利用摄像头扫描所有的传送带,把那些有零件的传送带编号告诉工人。 厂房后来扩建了,生产线又扩大了,原来的监视器无法覆盖全部的传送带,工人调整了摄像头的位置和个数,改进的了这个问题。但是这个方案并不完善,摄像头移动需要时间,传送带上配件出现的时候,摄像头的位置需要移动很长时间才能完全覆盖所有传送带,找到那些有零件出现的传送带的编号(无差别轮训),工人并不能及时的相应。 为了提高效率,工人想了一个办法,每次增加一个传送带,都在传送带另一侧放上一个传感器,他把监控器和传感器直接相连,当有传感器感应到有配件的到达的时候,监视器直接把所有有配件出现的传感器编号告诉给工人,这样工人的相应更加及时,这个方案也保持着稳定的效率。 说了这么多白话,我们再返回计算机系统里来理解这些容易混淆的概念。当进程调用系统IO方法的时候,比如发起一个http请求,接受 对应的http response的时候,如果系统IO方法(recvfrom)是立即返回那么这就是一个非阻塞的IO。阻塞IO通常需要在数据就绪后还要将数据从内核拷贝到请求的进程空间,然后才会返回成功。 对于非阻塞IO,如果执行忙轮询的是进程,进程根据recvfrom返回结果来确认数据是否已经就绪。这种基于系统IO接口的调用,每次只能确认一个流上数据状态。 并没有实现一次能够返回多个流的数据状态信息。 select/poll/epoll这些系统级别实现的方法就是相关进程的一个代理,它们可以同时监视多个流的状态。它们的主要区别是实现方式和性能上的,简单总结如下: select 能够监听的描述是有限的,并且因为需要遍历所有添加的描述符,性能上也是有损耗的。 poll 虽然监听数量不受打开描述符号限制,但是由于和select一样基于无差别轮询的方式,在大量连接,少数就绪的情况下,I/O的性能会有比较明显的下降。 epoll 支持的文件描述符上限是最大可以打开文件的数目, 并且基于事件单独注册了回调函数,所以在处理延迟和响应不是特别及时的WAN网上特别合适。 同步/异步(IO) 讲完了阻塞/非阻塞,我们再来看看同步的概念,这里的同步和异步指的是IO层面上,请不要于应用内函数调用混淆。进程在访问系统IO接口的时候,虽然接口返回了,把数据从内核中读入到自己 内存空间中,这个过程依然是同步和阻塞的。所以I/O多路复用依然是同步IO 异步IO应该是从调用系统IO接口开始到最后数据拷贝,进程并没有参与,而是收到就绪通知后拿来就用。这种模型在实际场景中应用的比较少,感兴趣的同学,可以自行搜索。 欢迎大家留言讨论,或者加入我们的Python的QQ学习群(278529278)共同学习。

Continue reading 


Python yield 使用浅析

󰃭 2017-03-09

转载: Python yield 使用浅析(@廖雪峰) 您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ? 我们先抛开 generator,以一个常见的编程题目来展示 yield 的概念。 如何生成斐波那契數列 斐波那契(Fibonacci)數列是一个非常简单的递归数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到。用计算机程序输出斐波那契數列的前 N 个数是一个非常简单的问题,许多初学者都可以轻易写出如下函数: 清单 1. 简单输出斐波那契數列前 N 个数 def fab(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1 执行 fab(5),我们可以得到如下输出: >>> fab(5) 1 1 2 3 5 结果没有问题,但有经验的开发者会指出,直接在 fab 函数中用 print 打印数字会导致该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列。 要提高 fab 函数的可复用性,最好不要直接打印出数列,而是返回一个 List。以下是 fab 函数改写后的第二个版本:

Continue reading 


理解python装饰器

󰃭 2017-03-09

理解python装饰器 装饰器(Derorators),正如其字面所描述,在原函数的基础上进行一些额外的操作。接下来我们将从源头出发,探探python的装饰器。 从函数开始 在日常的工作中,我们需要写形形色色的业务函数,如example 1: #example 1 def deal_business(arg): print("Dealing Business in {}".format(arg)) def main(): # in block 1 deal_business("block 1") # in block 2 deal_business("block 2") if __name__ == "__main__": main() 在某一天,你需要去统计在各个block中业务处理时间,比较朴素的方案如example 2: #example 2 import time def deal_business(arg): print("Dealing Business in {}".format(arg)) def main(): # in block 1 time_start_1 = time.clock() deal_business("block 1") time_end_1 = time.clock() print("time for block 1") # in block 2 time_start_2 = time.clock() deal_business("block 2") time_end_2 = time.

Continue reading 


mac virtualbox 设置共享剪切板和目录

󰃭 2017-03-07

原创作品:首发u3v3, 转载请保留 地址:https://www.u3v3.com/ar/1279 作者ID:Yi_Zhi_Yu 首发日期:2017.3.8 Python学习群:278529278 (欢迎交流) 前言 在之前的一篇文章里(Mac 系统安装使用virtualbox), 我们在mac上安装了 virtualbox 但安装好后, 发现不能往虚拟机中复制文件, 虚拟机中的文件也不能复制到主机中 现在, 我们就来设置一下, 让主机和虚拟机能够互通有无 说明 主机: mac os 10.12.3 虚拟机: win7 以及以下黏贴的图片, 出现虚拟机图片灰暗的问题说明: 因为我个人使用的mac, 在虚拟机操作的时候, 不能使用mac的截图工具, 所以将虚拟机暂停掉, 然后截图. 这时的灰暗就是暂停的迅疾状态, 各位可以忽略, 正常操作即可, 不需要暂停, 周知 复制黏贴 安装 Sun VirtualBox Guest Additions 这是virtualbox 上的一款增强扩展, 我们后续的复制剪切共享文件等操作需要依赖, 如何安装呢, 启动虚拟机, 然后在点击的虚拟机的窗口菜单上的Devices > Insert Guest Addtjions CD image… 虚拟机中弹出对话框, 点击运行 如图 这个过程中会有询问是否安装某些适配器, 点击安装, 否则安装会失败 安装完成后, 重启虚拟机 设置允许双向复制和拖曳文件操作 默认是 Disabled, 剩下的依次设置主机允许复制和拖曳的方向, 最后 Bidirectional 是允许双向操作的

Continue reading 