1.上节内容回顾

递归:

  • 明确的结束条件
  • 问题规模每递归一次都应该比上一次的问题规模有所减少
  • 效率低

高阶函数

文件:

rb、wb、ab

一般用在不同系统之间传数据,和传视频流的时候用到,一般以这种形式打开的需要制定encoding=‘utf-8’的字符编码形式

其他:

  • f.seek()
  • f.tell()
  • f.truncate()
  • f.flush()

2.装饰器

定义:装饰器本质是函数,(装饰其他函数)就是为其他函数添加附加功能

原则:

  • 不能修改被装饰的函数的源代码
  • 不能修改被装饰的函数的调用方式

言外之意就是说被装饰的函数在装饰器前都是完全透明的

实现装饰器知识储备:

  1. 函数即“变量”
  2. 高阶函数
      • 把一个函数名当做实参传给另外一个函数(不修改被装饰函数源代码的情况下为期添加功能)
      • 返回值中包含函数名(不修改函数的调用方式)

  3.嵌套函数

一、函数的调用顺序:函数就像变量一样,在定义的时候就是把函数体赋值给函数名这样子,Python在调用函数之前,该函数一定要先被声明

  1. def foo():
  2. print(foo)
  3. bar()
  4. foo()
  5. def bar():
  6. print(bar)
  7. #报错,bar函数还未声明

改正:

  1. def foo():
  2. print('foo')
  3. bar()
  4. def bar():
  5. print('bar')
  6. foo()
二、 高阶函数
  1. def bar():
  2. print 'in the bar'
  3. def foo(func):
  4. res=func()
  5. return res
  6. foo(bar)

三、嵌套函数

  1. def foo():
  2. def bar():
  3. print 'in the bar'
  4.  
  5. bar()
  6.  
  7. foo()

四、装饰器

装饰器的语法以@开头,接着就是装饰器要装饰的函数的声明

装饰器就是一个函数,一个用来包装函数的函数,装饰器在函数声明完成的时候被调用,调用之后声明的函数被换成一个被装饰器装饰过后的函数。

当函数有形参时,在装饰的函数中也需要有相应的形参;

当原函数有return返回值时,在装饰的函数中也要萹蓄有return func(args);

函数参数固定:

  1. def decorator(func):
  2. def wrapper(n):
  3. print('atarting')
  4. func(n)
  5. print('stopping')
  6. return wrapper
  7. def test(n):
  8. print('in the test arg is %s'%n)
  9. decorator(test)('alex')

函数参数不固定

  1. def decorator(func):
  2. def wrapper(*args,**kwargs):
  3. print('starting')
  4. func(*args,**kwargs)
  5. print('stopping')
  6. return wrapper
  7. def test(n,x=1):
  8. print('in the test arg is %s,he is %d'%(n,x))
  9. decorator(test)('alex',x=2)

  1.无参装饰器

  1. import time
  2. def decorator(func):
  3. def wrapper(*args,**kwargs):
  4. start =time.time()
  5. func(*args,**kwargs)
  6. stop = time.time()
  7. print('run time is %s'%(stop-start))
  8. return wrapper
  9. @decorator #test=decorator(test)
  10. def test(list_test):
  11. for i in list_test:
  12. time.sleep(0.1)
  13. print('_'*20,i)
  14. test(range(10))

  2.有参装饰器

  1. import time
  2. def timer(timeout =0):
  3. def decorator(func):
  4. def wrapper(*args,**kwargs):
  5. start = time.time()
  6. func(*args,**kwargs)
  7. stop = time.time()
  8. print("run time is %s"%(stop-start))
  9. print(timeout)
  10. return wrapper
  11. return decorator
  12. @timer(2) #test=timer(2)(test)
  13. def test(list_test):
  14. for i in list_test:
  15. time.sleep(0.1)
  16. print('-'*20,i)
  17. test(range(10))

高阶函数+嵌套函数=》装饰器

举一个复杂的例子:

  1. import time
  2. user,passwd = 'alex','abc123'
  3. def auth(auth_type):
  4. print("auth func:",auth_type)
  5. def outer_wrapper(func):
  6. def wrapper(*args, **kwargs):
  7. print("wrapper func args:", *args, **kwargs)
  8. if auth_type == "local":
  9. username = input("Username:").strip()
  10. password = input("Password:").strip()
  11. if user == username and passwd == password:
  12. print("\033[32;1mUser has passed authentication\033[0m")
  13. res = func(*args, **kwargs) # from home
  14. print("---after authenticaion ")
  15. return res
  16. else:
  17. exit("\033[31;1mInvalid username or password\033[0m")
  18. elif auth_type == "ldap":
  19. print("搞毛线ldap,不会。。。。")
  20.  
  21. return wrapper
  22. return outer_wrapper
  23.  
  24. def index():
  25. print("welcome to index page")
  26. @auth(auth_type="local") # home = wrapper()
  27. def home():
  28. print("welcome to home page")
  29. return "from home"
  30.  
  31. @auth(auth_type="ldap")
  32. def bbs():
  33. print("welcome to bbs page")
  34.  
  35. index()
  36. print(home()) #wrapper()
  37. bbs()

3.列表生成式,迭代器&生成器

生成器只有在调用时才会生成相应的数据

只记录当前的位置

只有一个__next__()方法,next()

列表生成式:

需求:将列表[0,1,2,3,4,5,6,7,8,9]将列表里的每个值加1、

三种写法:

  1. a =[0,1,2,3,4,5,6,7,8,9]
  2. b =[]
  3. for i in a:
  4. b.append(i+1)
  5. a =b
  6. print(a)

第一种

  1. a = [1,2,3,4,5,6,7,8,9]
  2. a =map(lambda x:x+1,a) #map(f(x),列表名)
  3. for i in a:
  4. print(i)

第二种

  1. a= [i+1 for i in range(10)]
  2. for i in a:
  3. print(i)

第三种

第三种即就是列表生成式

生成器:

通过列表生成式,我们可以直接创建一个列表,但是要创建100万个元素的列表,那么存储空间很庞大,因此,我们只需要生成式,它就是不必创建完整的list,从而节省大量空间,这种一遍循环一边计算的机制,称为生成器:generator

创建generetor有以下几种方法:

第一种:把列表生成式的[]改为(),就创建了一个generator

  1. >>> L = [x * x for x in range(10)]
  2. >>> L
  3. [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
  4. >>> g = (x * x for x in range(10))
  5. >>> g
  6. <generator object <genexpr> at 0x1022ef630>

此时g已经是一个生成器

如何一个个打印出来,用next()函数即可

  1. >>> next(g)
  2. 0
  3. >>> next(g)
  4. 1
  5. >>> next(g)
  6. 4
  7. >>> next(g)
  8. 9
  9. >>> next(g)
  10. 16
  11. >>> next(g)
  12. 25
  13. >>> next(g)
  14. 36
  15. >>> next(g)
  16. 49
  17. >>> next(g)
  18. 64
  19. >>> next(g)
  20. 81
  21. >>> next(g)
  22. Traceback (most recent call last):
  23. File "<stdin>", line 1, in <module>
  24. StopIteration

generator保存的是算法,每次调用next(),就计算出g的下一个元素的值,直到计算出最后一个元素,没有更多的元素时,跑出StopIteration错误

不断调用next()方法太麻烦,因此用for循环,此种方法也不需要考虑StopIteration错误

  1. >>> g = (x * x for x in range(10))
  2. >>> for n in g:
  3. ... print(n)
  4. ...
  5. 0
  6. 1
  7. 4
  8. 9
  9. 16
  10. 25
  11. 36
  12. 49
  13. 64
  14. 81

打印斐波拉契数列:

斐波拉契数列(Fibonacci):1, 1, 2, 3, 5, 8, 13, 21, 34, ...

  1. def fib(max):
  2. n,a,b=0,0,1
  3. while n<max:
  4. print(b)
  5. a,b=b,a+b
  6. n =n+1
  7. return 'done'

fib函数实际上定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑很类似generator。

要把fib()变成generator,只需要把print(b)改为yield(b)即可

  1. def fib(max):
  2. n,a,b=0,0,1
  3. while n<max:
  4. #print(b)
  5. yield b
  6. a,b=b,a+b
  7. n =n+1
  8. return done
  1. >>> f = fib(6)
  2. >>> f
  3. <generator object fib at 0x104feaaa0>

generator,在每次调用next()执行,遇到yield就返回,再次执行则从上次返回的yield语句处继续执行

  1. data = fib(10)
  2. print(data)
  3.  
  4. print(data.__next__())
  5. print(data.__next__())
  6. print("干点别的事")
  7. print(data.__next__())
  8. print(data.__next__())
  9. print(data.__next__())
  10. print(data.__next__())
  11. print(data.__next__())
  12.  
  13. #输出
  14. <generator object fib at 0x101be02b0>
  15. 1
  16. 1
  17. 干点别的事
  18. 2
  19. 3
  20. 5
  21. 8
  22. 13

在循环过程中不断调用yield,就会不断中断,当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

把函数变成generator之后,基本不会用next()来获取下一个返回值,而是直接使用for循环来迭代:

  1. >>> for n in fib(6):
  2. ... print(n)
  3. ...
  4. 1
  5. 1
  6. 2
  7. 3
  8. 5
  9. 8

在用for循环调用generator时,发现拿不到generator的return语句的返回值,如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

  1. >>> g = fib(6)
  2. >>> while True:
  3. ... try:
  4. ... x = next(g)
  5. ... print('g:', x)
  6. ... except StopIteration as e:
  7. ... print('Generator return value:', e.value)
  8. ... break
  9. ...
  10. g: 1
  11. g: 1
  12. g: 2
  13. g: 3
  14. g: 5
  15. g: 8
  16. Generator return value: done

还可以使用yield实现单线程的情况下并发运算的效果

  1. #_*_coding:utf-8_*_
  2. __author__ = 'Alex Li'
  3.  
  4. import time
  5. def consumer(name):
  6. print("%s 准备吃包子啦!" %name)
  7. while True:
  8. baozi = yield
  9.  
  10. print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
  11.  
  12. def producer(name):
  13. c = consumer('A')
  14. c2 = consumer('B')
  15. c.__next__()
  16. c2.__next__()
  17. print("老子开始准备做包子啦!")
  18. for i in range(10):
  19. time.sleep(1)
  20. print("做了2个包子!")
  21. c.send(i)
  22. c2.send(i)
  23.  
  24. producer("alex")
  25.  
  26. #通过生成器实现协程并行运算

迭代器:

直接作用于for循环的数据类型以下几种:

一类是集合数据类型:列表(list),元组(tuple),字典(dict),集合(set),字符串(str)等

一类是generator,包括生成器和带yield的generator function。

这类可直接作用于for循环的对象统称为可迭代对象:Tterable

可以使用isinstance()判断一个对象是是否是Iterrator对象:

  1. >>> from collections import Iterable
  2. >>> isinstance([], Iterable)
  3. True
  4. >>> isinstance({}, Iterable)
  5. True
  6. >>> isinstance('abc', Iterable)
  7. True
  8. >>> isinstance((x for x in range(10)), Iterable)
  9. True
  10. >>> isinstance(100, Iterable)
  11. False

而生成器不但可以作用于for循环,还可以被next()函数不断调用并但会下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一值的对象称为迭代器:Iterator

可以使用isinstance()判断一个对象是否是Iterator对象:

  1. >>> from collections import Iterator
  2. >>> isinstance((x for x in range(10)), Iterator)
  3. True
  4. >>> isinstance([], Iterator)
  5. False
  6. >>> isinstance({}, Iterator)
  7. False
  8. >>> isinstance('abc', Iterator)
  9. False

由此可知:生成器都是Iterator对象,但列表、字典、字符串虽然是Iterable但不是Iterator

小结:

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,他们表示一个惰性极端的序列(即只有在需要的时候才会计算,不需要则不会计算);

集合数据类型如:列表、字典、字符串,集合等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

如for新欢本质上是通过不断调用next()函数实现的:

for x in [1, 2, 3, 4, 5]: pass

实际上等价于:

  1. # 首先获得Iterator对象:
  2. it = iter([1, 2, 3, 4, 5])
  3. # 循环:
  4. while True:
  5. try:
  6. # 获得下一个值:
  7. x = next(it)
  8. except StopIteration:
  9. # 遇到StopIteration就退出循环
  10. break

4.内置函数

见博客地址:

5.软件目录结构规范

Python3的更多相关文章

  1. python3  threading初体验

    python3中thread模块已被废弃,不能在使用thread模块,为了兼容性,python3将thread命名为_thread.python3中我们可以使用threading进行代替. threa ...

  2. Python3中的字符串函数学习总结

    这篇文章主要介绍了Python3中的字符串函数学习总结,本文讲解了格式化类方法.查找 & 替换类方法.拆分 & 组合类方法等内容,需要的朋友可以参考下. Sequence Types ...

  3. Mac-OSX的Python3.5虚拟环境下安装Opencv

    Mac-OSX的Python3.5虚拟环境下安装Opencv 1   关键词 关键词:Mac,OSX,Python3.5,Virtualenv,Opencv 2   概述 本文是一篇 环境搭建 的基础 ...

  4. Ubuntu部署python3.5的开发和运行环境

    Ubuntu部署python3.5的开发和运行环境 1 概述 由于最近项目全部由python2.x转向 python3.x(使用目前最新的 python3.5.1) ,之前的云主机的的默认python ...

  5. Python3 登陆网页并保持cookie

    网页登陆 网页登陆的原理都是,保持一个sessionid在cookie然后,根据sessionid在服务端找到cookie进行用户识别 python实现 由于python的简单以及丰富的类库是开发网络 ...

  6. 阿里云 SDK python3支持

    最近的一个项目需要操作阿里云的RDS,项目使用python3,让人惊讶的是官方的SDK竟然只支持python2 在阿里云现有SDK上改了改,文件的修改只涉及aliyun/api/base.py,详见h ...

  7. python3爬取1024图片

    这两年python特别火,火到博客园现在也是隔三差五的出现一些python的文章.各种开源软件.各种爬虫算法纷纷开路,作为互联网行业的IT狗自然看的我也是心痒痒,于是趁着这个雾霾横行的周末瞅了两眼,作 ...

  8. CentOS7中安装Python3.5

    1.下载 https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz 2.上传到服务器 3. 安装相关依赖 yum install gcc ope ...

  9. 使用virtualenv搭建python3开发环境

    问题描述 环境: CentOS6.5 想在此环境下使用python3进行开发,但CentOS6.5默认的python环境是2.6.6版本. 之前的做法是直接从源码安装python3,替换掉现有的开发环 ...

  10. 烂泥:python2.7和python3.5源码安装

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 前几天在centos6.6安装ansible时,一直提示python版本不对,导致不能安 ...

随机推荐

  1. 管道过滤器模式(Pipe and Filter)与组合模式(修改)

    转自:http://haolloyin.blog.51cto.com/1177454/348277 之前在 benjielin 前辈的博客中看到“管道过滤器(Pipe-And-Filter)模式(ht ...

  2. Windows系统

    1. 更改XP登录界面 怎样启用XP的经典登录界面 第一步:用管理员账号登录系统. 第二步:运行gpedit.msc启动组策略编辑器,找到"计算机配置"--"管理模板&q ...

  3. 第一周:Java基础知识总结(1)

    1.软件开发的基本步骤: 1.分析问题,建立数据模型. 2.确定数据结构类型和算法. 3.编写程序. 4.调试程序. 2.Java语言 Java是一种简单的.面向对象的.分布式的.解释的.安全的.可移 ...

  4. IIS 平台NET无后缀名伪静态实现办法

    使用URLRewrite重写链接地址时,当无后缀时,总是找不到文件,不能使用.例如:http://shop.iccoo.cn/7648/ 无后缀形式(当然这个是可以的啦,只是看下链接形式) 当有后缀时 ...

  5. UNIX网络编程-非阻塞connect和非阻塞accept

    1.非阻塞connect 在看了很多资料之后,我自己的理解是:在socket发起一次连接的时候,这个过程需要一段时间来将三次握手的过程走完,如果在网络状况不好或者是其他的一些情况下,这个过程需要比较长 ...

  6. the import javax.servlet

    问题: 在eclipse中编写servlet时出现“the import javax.servlet unresolved” 问题原因: 缺少servlet-api.jar架包. 问题解决办法: 在e ...

  7. 将txt文件转换成EXCEL文件的方法

    地址:http://wenku.baidu.com/view/fcdbe8cca1c7aa00b52acbad.html 1.在EXCEL程序中点击“打开”,将文件类型选择为“文本文件”,找到以前用过 ...

  8. Web前端工程师

    前端开发,不仅仅是需要会写页面而已,还需要具备很多技能,现做如下总结: 会点设计,不要求精湛,处理图片,设计个小广告是要的: 精通HTML+CSS,并能快速处理各浏览器兼容问题: 熟练掌握Javasc ...

  9. iOS 趣谈设计模式——通知

    [前言介绍] iOS的一种设计模式,观察者Observer模式(也叫发布/订阅,即Publich/Subscribe模式). 观察者模式,包含了通知机制(notification)和KVO(Key-v ...

  10. 升级python2.7至python3

    首先下载源tar包 可利用linux自带下载工具wget下载,如下所示: 这里我用下载的是Python-3.5.1.tar.bz2版本,下载完成后到下载目录下,解压 进入解压缩后的文件夹 cd  Py ...