本文是我看了http://python.jobbole.com/88291/后加上自己的一些感想所创 我们都知道,IO比CPU慢很多个数量级,而传统的IO,是阻塞型的,CPU花在等待IO上的时间很多,那么想要提高并发量,选择解决CPU在等待IO上花费的大量时间是一个比较好的出路。 先来看一个阻塞型IO的例子。 同步阻塞下载程序 该脚本的功能是下载10个网页。 import socket urls = ['/'+str(i) for i in range(10)] host = 'www.baidu.com' def fn(url): sock = socket.socket() sock.connect((host,80)) # 这里会阻塞直到发送成功 #send不会阻塞 sock.send(('GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' % (url,host)).encode('utf-8')) respon 继续阅读 >>


李余通 18/04/24 23:53:57
Python中一共有三种推导式,做一个简述。 推导式的结构 开始符号 处理结果 迭代对象 过滤条件 结束符号 列表推导式 读取输入的内容并转成整数。 [int(x) for x in sys.stdin.readline().split() if x != '\n'] 开始符号:[ 结束符号:] 处理结果:int(x) 迭代对象:for x in sys.stdin.readline().split() 过滤条件:if x != '\n' #实际上这句话可以不要 会生成一个类似[1,2,3,4]的列表 生成器表达式 这个和列表推导式很类似,只是开始符号和结束符号变成了()。 生成器的好处是惰性计算,不会一下子占用太多内存。 集合推导式 这个和列表推导式很类似,只是开始符号和结束符号变成了{}。 {x**2 for x in [1,2,3,4,1,2,3] if x != 1} ==>{16, 9, 4} 字典推导式 符号:{} 处理结果k:v #e 继续阅读 >>


李余通 18/04/22 10:23:44
这个需求比较奇怪,要求实现Sum和MagaSum函数,实现以下功能 Sum(1) =>1 Sum(1,2,3) =>6 MegaSum(1)() =>1 MegaSum(1)(2)(3)() =>6 实际上Sum就是Python自建的sum函数,它支持变参,变参怎么实现,自然是*args,所以很容易写出雏形: Sum def Sum(*args): count = 0 for i in args: count+=i return count 第二个函数就有点皮了,它要求有参数的时候,返回的值是一个函数的引用,无参数的时候,返回的是结果。 要实现可以有或无参数,那么首想到的是Python的默认参数。我们可以默认参数值是None,当主动传入参数时,返回一个函数的引用,否则,返回结果。这里用到了Python可变类型作为函数参数时的一些特性。代码如下: def Sum(*args): s = 0 for i i 继续阅读 >>


李余通 18/04/15 20:50:14
很多时候,我们需要对已经实现的功能进行扩展,即增加新的功能,那么,最容易想到的就是就是对原有功能进行修改,这个时候免不了要修改原始代码,但面向对象编程的一个思想是开放封闭原则,即: 开放:对扩展开发 封闭:对已实现的功能模块 已实现的功能可以被扩展,不能被修改 需求来了 现在有一个函数 def do(msg): print("do %s..." % msg) 现在要求执行do之前打印一句before do...,执行完之后打印一句end do... 很容易想到这样的做法: def other_do(msg): print('before do...') do(msg) print('end do...') 功能达到了,但是有一个问题,我实际调用的函数已经不是do(msg),而是other_do(msg)了,那么有没有什么别的方法呢? 答案是装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功 继续阅读 >>


李余通 18/04/10 18:20:13
本文需要您有Python变量查找的知识,如果您不知道,可以参考上篇博文Python变量查找LEGB原则 构成闭包的条件 外函数中定义了内函数 内函数使用了外函数的变量 外函数的返回值是内函数的引用 以下是一个简单的闭包的定义 def outer(): b = 1 def inner(): #外部函数内定义了内部函数 print(b) #内部函数使用了外部函数的变量 return inner #外部函数的返回值是内函数的引用 使用 a = outer() a() #1 我们先是调用了外部函数outer()将其返回值赋值给了a变量,那么a变量实际上是指向的内部函数inner,当我们调用a时,相当于调用了inner,然后打印了外部变量b的值。 似乎没什么不妥 但是,我们知道,函数中的局部变量,在函数结束时会释放掉,但是上例中,执行a()的时候outer()已经退出了,那么对应的b也就释放了,但是inner还调用了b变量,这就是闭包。 闭包变 继续阅读 >>


李余通 18/04/08 21:02:36
两种类型 首先要知道Python的基本数据类型分为2种,可变以及不可变类型。 可变类型list dict set 不可变类型 number tuple string 变量访问 LEGB L-Local(function);函数内的名字空间 E-Enclosing function locals;外部嵌套函数的名字空间(例如closure) G-Global(module);函数定义所在模块(文件)的名字空间 B-Builtin(Python);Python内置模块的名字空间 当Python访问变量值时,默认LEGB查找原则,如果都找不到,则会抛出NameError 变量修改 但是,作为对变量值进行修改,则会有两种情况: 不可变变量 仅访问 a=10 def b(): print(a) #10 b() print(a) #10 可以正常访问,根据LEGB原则找到全局变量 仅修改 a=10 def b(): a = 20 print( 继续阅读 >>


李余通 18/04/08 14:39:42
这篇博文比较简单,就不分那么多的层次。 实现了__call__方法的对象,相当于重载了(),可以实现调用功能。 eg class A(): def __call__(self,name): print("%s is running!" % name) >>> a = A() >>> a("people") people is running! 首先,我们创建了A类的实例,赋值给a,由于A类实现了__call__方法,所以它可以调用,调用它实现了打印一句话,当然,这很无聊,实现非波纳契数列的类。 # coding=utf-8 """用类实现斐波那契数列""" class Fib(): def __call__(self, *args, **kwargs): ret = [1,1] num = int(args[0]) if num == 1: r 继续阅读 >>


李余通 18/04/01 21:52:52
python中的类 type这个方法有什么用? 首先纠正一个错误,type并非一个方法,而是一个类(扎心了老铁)。 >>> type(dict) <class 'type'> >>> type(type) <class 'type'> >>> type(object) <class 'type'> 很奇怪的一个现象,似乎所有类都是type类,不是说所有类都是从object继承来的啊,为什么连object自己都是type类型呢? 这要归功于Python是一种解释型语言,并非像C++,Java一样属于编译型语言,在编译型语言中,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现。而动态语言,则是在运行期间创建类,那么怎么创建类,其实就是用的type。 定义类的两种方法 # 直接定义 class Hello(object): 'Hello' 继续阅读 >>


李余通 18/03/31 21:16:43
基础协程实现方法 协程的实现主要靠的是yield关键字,yield的作用 挂起当前函数,将yield后面的值当做返回给调用生成器的地方;能够在唤醒生成器函数的时候,回复代码继续紧接着从上次执行的地方执行(可以接受额外的参数) def func1(n): for i in range(n): print('func1:before yield,i=%d' % i) x = yield print('func1:after yield,i=%d,x=%s' % (i,x)) def func2(n): for i in range(n): print('func2:before yield,i=%d' % i) x = yield print('func2:after yield,i=%d,x=%s' % (i,x)) a = func1(5) print(type(a)) = 继续阅读 >>


李余通 18/03/20 14:33:48
何为观察者模式 例子引出问题 现在有一颗苹果树,以及两个人,一个是负责种树的人,一个是负责吃苹果的人。 如果苹果树病了,种树的人要去治疗树,否则什么也不干; 如果树结果了,吃苹果的人要去吃,否则什么也不干; 那么如果苹果树的状态发生变化,种树者和食果者都要去得知树的状态,决定自己是否该行动。但是,两个人都不可能知道什么时候树产生变化,而时时刻刻去查看树的变化显然是不理想的。 解决方法 而观察者模式即使用来解决这个问题的。 系统中,苹果树作为被观察者,人作为观察者,即人会观察苹果树的状态(实际上是苹果树会将自己状态变化告知给人)。 作为被观察者,苹果树要有以下功能: 苹果树将要对自己负责的人放入自己观察者列表中,即实现registerObserver(self,observer)方法 当苹果树状态改变时(苹果树自然知道自身状态什么时候发生改变),会对自己的观察者列表的人发一条消息推送,即实现notifyObservers(self)方法 当不在需要某个人观察自己时(即状态改变后 继续阅读 >>


李余通 18/03/13 16:00:46