Python3
1.上节内容回顾
递归:
- 明确的结束条件
- 问题规模每递归一次都应该比上一次的问题规模有所减少
- 效率低
高阶函数
文件:
rb、wb、ab
一般用在不同系统之间传数据,和传视频流的时候用到,一般以这种形式打开的需要制定encoding=‘utf-8’的字符编码形式
其他:
- f.seek()
- f.tell()
- f.truncate()
- f.flush()
2.装饰器
定义:装饰器本质是函数,(装饰其他函数)就是为其他函数添加附加功能
原则:
- 不能修改被装饰的函数的源代码
- 不能修改被装饰的函数的调用方式
言外之意就是说被装饰的函数在装饰器前都是完全透明的
实现装饰器知识储备:
- 函数即“变量”
- 高阶函数
- 把一个函数名当做实参传给另外一个函数(不修改被装饰函数源代码的情况下为期添加功能)
- 返回值中包含函数名(不修改函数的调用方式)
3.嵌套函数
一、函数的调用顺序:函数就像变量一样,在定义的时候就是把函数体赋值给函数名这样子,Python在调用函数之前,该函数一定要先被声明
- def foo():
- print(foo)
- bar()
- foo()
- def bar():
- print(bar)
- #报错,bar函数还未声明
改正:
- def foo():
- print('foo')
- bar()
- def bar():
- print('bar')
- foo()
二、 高阶函数
- def bar():
- print 'in the bar'
- def foo(func):
- res=func()
- return res
- foo(bar)
三、嵌套函数
- def foo():
- def bar():
- print 'in the bar'
- bar()
- foo()
四、装饰器
装饰器的语法以@开头,接着就是装饰器要装饰的函数的声明
装饰器就是一个函数,一个用来包装函数的函数,装饰器在函数声明完成的时候被调用,调用之后声明的函数被换成一个被装饰器装饰过后的函数。
当函数有形参时,在装饰的函数中也需要有相应的形参;
当原函数有return返回值时,在装饰的函数中也要萹蓄有return func(args);
函数参数固定:
- def decorator(func):
- def wrapper(n):
- print('atarting')
- func(n)
- print('stopping')
- return wrapper
- def test(n):
- print('in the test arg is %s'%n)
- decorator(test)('alex')
函数参数不固定
- def decorator(func):
- def wrapper(*args,**kwargs):
- print('starting')
- func(*args,**kwargs)
- print('stopping')
- return wrapper
- def test(n,x=1):
- print('in the test arg is %s,he is %d'%(n,x))
- decorator(test)('alex',x=2)
1.无参装饰器
- import time
- def decorator(func):
- def wrapper(*args,**kwargs):
- start =time.time()
- func(*args,**kwargs)
- stop = time.time()
- print('run time is %s'%(stop-start))
- return wrapper
- @decorator #test=decorator(test)
- def test(list_test):
- for i in list_test:
- time.sleep(0.1)
- print('_'*20,i)
- test(range(10))
2.有参装饰器
- import time
- def timer(timeout =0):
- def decorator(func):
- def wrapper(*args,**kwargs):
- start = time.time()
- func(*args,**kwargs)
- stop = time.time()
- print("run time is %s"%(stop-start))
- print(timeout)
- return wrapper
- return decorator
- @timer(2) #test=timer(2)(test)
- def test(list_test):
- for i in list_test:
- time.sleep(0.1)
- print('-'*20,i)
- test(range(10))
高阶函数+嵌套函数=》装饰器
举一个复杂的例子:
- import time
- user,passwd = 'alex','abc123'
- def auth(auth_type):
- print("auth func:",auth_type)
- def outer_wrapper(func):
- def wrapper(*args, **kwargs):
- print("wrapper func args:", *args, **kwargs)
- if auth_type == "local":
- username = input("Username:").strip()
- password = input("Password:").strip()
- if user == username and passwd == password:
- print("\033[32;1mUser has passed authentication\033[0m")
- res = func(*args, **kwargs) # from home
- print("---after authenticaion ")
- return res
- else:
- exit("\033[31;1mInvalid username or password\033[0m")
- elif auth_type == "ldap":
- print("搞毛线ldap,不会。。。。")
- return wrapper
- return outer_wrapper
- def index():
- print("welcome to index page")
- @auth(auth_type="local") # home = wrapper()
- def home():
- print("welcome to home page")
- return "from home"
- @auth(auth_type="ldap")
- def bbs():
- print("welcome to bbs page")
- index()
- print(home()) #wrapper()
- bbs()
3.列表生成式,迭代器&生成器
生成器只有在调用时才会生成相应的数据
只记录当前的位置
只有一个__next__()方法,next()
列表生成式:
需求:将列表[0,1,2,3,4,5,6,7,8,9]将列表里的每个值加1、
三种写法:
- a =[0,1,2,3,4,5,6,7,8,9]
- b =[]
- for i in a:
- b.append(i+1)
- a =b
- print(a)
第一种
- a = [1,2,3,4,5,6,7,8,9]
- a =map(lambda x:x+1,a) #map(f(x),列表名)
- for i in a:
- print(i)
第二种
- a= [i+1 for i in range(10)]
- for i in a:
- print(i)
第三种
第三种即就是列表生成式
生成器:
通过列表生成式,我们可以直接创建一个列表,但是要创建100万个元素的列表,那么存储空间很庞大,因此,我们只需要生成式,它就是不必创建完整的list,从而节省大量空间,这种一遍循环一边计算的机制,称为生成器:generator
创建generetor有以下几种方法:
第一种:把列表生成式的[]改为(),就创建了一个generator
- >>> L = [x * x for x in range(10)]
- >>> L
- [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
- >>> g = (x * x for x in range(10))
- >>> g
- <generator object <genexpr> at 0x1022ef630>
此时g已经是一个生成器
如何一个个打印出来,用next()函数即可
- >>> next(g)
- 0
- >>> next(g)
- 1
- >>> next(g)
- 4
- >>> next(g)
- 9
- >>> next(g)
- 16
- >>> next(g)
- 25
- >>> next(g)
- 36
- >>> next(g)
- 49
- >>> next(g)
- 64
- >>> next(g)
- 81
- >>> next(g)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- StopIteration
generator保存的是算法,每次调用next(),就计算出g的下一个元素的值,直到计算出最后一个元素,没有更多的元素时,跑出StopIteration错误
不断调用next()方法太麻烦,因此用for循环,此种方法也不需要考虑StopIteration错误
- >>> g = (x * x for x in range(10))
- >>> for n in g:
- ... print(n)
- ...
- 0
- 1
- 4
- 9
- 16
- 25
- 36
- 49
- 64
- 81
打印斐波拉契数列:
斐波拉契数列(Fibonacci):1, 1, 2, 3, 5, 8, 13, 21, 34, ...
- def fib(max):
- n,a,b=0,0,1
- while n<max:
- print(b)
- a,b=b,a+b
- n =n+1
- return 'done'
fib函数实际上定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑很类似generator。
要把fib()变成generator,只需要把print(b)改为yield(b)即可
- def fib(max):
- n,a,b=0,0,1
- while n<max:
- #print(b)
- yield b
- a,b=b,a+b
- n =n+1
- return ‘done'
- >>> f = fib(6)
- >>> f
- <generator object fib at 0x104feaaa0>
generator,在每次调用next()执行,遇到yield就返回,再次执行则从上次返回的yield语句处继续执行
- data = fib(10)
- print(data)
- print(data.__next__())
- print(data.__next__())
- print("干点别的事")
- print(data.__next__())
- print(data.__next__())
- print(data.__next__())
- print(data.__next__())
- print(data.__next__())
- #输出
- <generator object fib at 0x101be02b0>
- 1
- 1
- 干点别的事
- 2
- 3
- 5
- 8
- 13
在循环过程中不断调用yield,就会不断中断,当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。
把函数变成generator之后,基本不会用next()来获取下一个返回值,而是直接使用for循环来迭代:
- >>> for n in fib(6):
- ... print(n)
- ...
- 1
- 1
- 2
- 3
- 5
- 8
在用for循环调用generator时,发现拿不到generator的return语句的返回值,如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
- >>> g = fib(6)
- >>> while True:
- ... try:
- ... x = next(g)
- ... print('g:', x)
- ... except StopIteration as e:
- ... print('Generator return value:', e.value)
- ... break
- ...
- g: 1
- g: 1
- g: 2
- g: 3
- g: 5
- g: 8
- Generator return value: done
还可以使用yield实现单线程的情况下并发运算的效果
- #_*_coding:utf-8_*_
- __author__ = 'Alex Li'
- import time
- def consumer(name):
- print("%s 准备吃包子啦!" %name)
- while True:
- baozi = yield
- print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
- def producer(name):
- c = consumer('A')
- c2 = consumer('B')
- c.__next__()
- c2.__next__()
- print("老子开始准备做包子啦!")
- for i in range(10):
- time.sleep(1)
- print("做了2个包子!")
- c.send(i)
- c2.send(i)
- producer("alex")
- #通过生成器实现协程并行运算
迭代器:
直接作用于for循环的数据类型以下几种:
一类是集合数据类型:列表(list),元组(tuple),字典(dict),集合(set),字符串(str)等
一类是generator,包括生成器和带yield的generator function。
这类可直接作用于for循环的对象统称为可迭代对象:Tterable
可以使用isinstance()判断一个对象是是否是Iterrator对象:
- >>> from collections import Iterable
- >>> isinstance([], Iterable)
- True
- >>> isinstance({}, Iterable)
- True
- >>> isinstance('abc', Iterable)
- True
- >>> isinstance((x for x in range(10)), Iterable)
- True
- >>> isinstance(100, Iterable)
- False
而生成器不但可以作用于for循环,还可以被next()函数不断调用并但会下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
可以被next()函数调用并不断返回下一值的对象称为迭代器:Iterator
可以使用isinstance()判断一个对象是否是Iterator对象:
- >>> from collections import Iterator
- >>> isinstance((x for x in range(10)), Iterator)
- True
- >>> isinstance([], Iterator)
- False
- >>> isinstance({}, Iterator)
- False
- >>> isinstance('abc', Iterator)
- False
由此可知:生成器都是Iterator对象,但列表、字典、字符串虽然是Iterable但不是Iterator
小结:
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,他们表示一个惰性极端的序列(即只有在需要的时候才会计算,不需要则不会计算);
集合数据类型如:列表、字典、字符串,集合等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
如for新欢本质上是通过不断调用next()函数实现的:
for x in [1, 2, 3, 4, 5]: pass
实际上等价于:
- # 首先获得Iterator对象:
- it = iter([1, 2, 3, 4, 5])
- # 循环:
- while True:
- try:
- # 获得下一个值:
- x = next(it)
- except StopIteration:
- # 遇到StopIteration就退出循环
- break
4.内置函数
见博客地址:
5.软件目录结构规范
Python3的更多相关文章
- python3 threading初体验
python3中thread模块已被废弃,不能在使用thread模块,为了兼容性,python3将thread命名为_thread.python3中我们可以使用threading进行代替. threa ...
- Python3中的字符串函数学习总结
这篇文章主要介绍了Python3中的字符串函数学习总结,本文讲解了格式化类方法.查找 & 替换类方法.拆分 & 组合类方法等内容,需要的朋友可以参考下. Sequence Types ...
- Mac-OSX的Python3.5虚拟环境下安装Opencv
Mac-OSX的Python3.5虚拟环境下安装Opencv 1 关键词 关键词:Mac,OSX,Python3.5,Virtualenv,Opencv 2 概述 本文是一篇 环境搭建 的基础 ...
- Ubuntu部署python3.5的开发和运行环境
Ubuntu部署python3.5的开发和运行环境 1 概述 由于最近项目全部由python2.x转向 python3.x(使用目前最新的 python3.5.1) ,之前的云主机的的默认python ...
- Python3 登陆网页并保持cookie
网页登陆 网页登陆的原理都是,保持一个sessionid在cookie然后,根据sessionid在服务端找到cookie进行用户识别 python实现 由于python的简单以及丰富的类库是开发网络 ...
- 阿里云 SDK python3支持
最近的一个项目需要操作阿里云的RDS,项目使用python3,让人惊讶的是官方的SDK竟然只支持python2 在阿里云现有SDK上改了改,文件的修改只涉及aliyun/api/base.py,详见h ...
- python3爬取1024图片
这两年python特别火,火到博客园现在也是隔三差五的出现一些python的文章.各种开源软件.各种爬虫算法纷纷开路,作为互联网行业的IT狗自然看的我也是心痒痒,于是趁着这个雾霾横行的周末瞅了两眼,作 ...
- CentOS7中安装Python3.5
1.下载 https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz 2.上传到服务器 3. 安装相关依赖 yum install gcc ope ...
- 使用virtualenv搭建python3开发环境
问题描述 环境: CentOS6.5 想在此环境下使用python3进行开发,但CentOS6.5默认的python环境是2.6.6版本. 之前的做法是直接从源码安装python3,替换掉现有的开发环 ...
- 烂泥:python2.7和python3.5源码安装
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 前几天在centos6.6安装ansible时,一直提示python版本不对,导致不能安 ...
随机推荐
- 管道过滤器模式(Pipe and Filter)与组合模式(修改)
转自:http://haolloyin.blog.51cto.com/1177454/348277 之前在 benjielin 前辈的博客中看到“管道过滤器(Pipe-And-Filter)模式(ht ...
- Windows系统
1. 更改XP登录界面 怎样启用XP的经典登录界面 第一步:用管理员账号登录系统. 第二步:运行gpedit.msc启动组策略编辑器,找到"计算机配置"--"管理模板&q ...
- 第一周:Java基础知识总结(1)
1.软件开发的基本步骤: 1.分析问题,建立数据模型. 2.确定数据结构类型和算法. 3.编写程序. 4.调试程序. 2.Java语言 Java是一种简单的.面向对象的.分布式的.解释的.安全的.可移 ...
- IIS 平台NET无后缀名伪静态实现办法
使用URLRewrite重写链接地址时,当无后缀时,总是找不到文件,不能使用.例如:http://shop.iccoo.cn/7648/ 无后缀形式(当然这个是可以的啦,只是看下链接形式) 当有后缀时 ...
- UNIX网络编程-非阻塞connect和非阻塞accept
1.非阻塞connect 在看了很多资料之后,我自己的理解是:在socket发起一次连接的时候,这个过程需要一段时间来将三次握手的过程走完,如果在网络状况不好或者是其他的一些情况下,这个过程需要比较长 ...
- the import javax.servlet
问题: 在eclipse中编写servlet时出现“the import javax.servlet unresolved” 问题原因: 缺少servlet-api.jar架包. 问题解决办法: 在e ...
- 将txt文件转换成EXCEL文件的方法
地址:http://wenku.baidu.com/view/fcdbe8cca1c7aa00b52acbad.html 1.在EXCEL程序中点击“打开”,将文件类型选择为“文本文件”,找到以前用过 ...
- Web前端工程师
前端开发,不仅仅是需要会写页面而已,还需要具备很多技能,现做如下总结: 会点设计,不要求精湛,处理图片,设计个小广告是要的: 精通HTML+CSS,并能快速处理各浏览器兼容问题: 熟练掌握Javasc ...
- iOS 趣谈设计模式——通知
[前言介绍] iOS的一种设计模式,观察者Observer模式(也叫发布/订阅,即Publich/Subscribe模式). 观察者模式,包含了通知机制(notification)和KVO(Key-v ...
- 升级python2.7至python3
首先下载源tar包 可利用linux自带下载工具wget下载,如下所示: 这里我用下载的是Python-3.5.1.tar.bz2版本,下载完成后到下载目录下,解压 进入解压缩后的文件夹 cd Py ...