Python初识 - day5
一、装饰器(decorator)
1.定义:本质是函数(装饰其它函数),就是为了其它函数添加附加功能。
2.原则:一是不能修改被装饰函数的源代码;二是不能修改被装饰函数的调用方式。
3.装饰器包含的知识点:
<1>函数(可作为变量)
<2>高阶函数
a.把一个函数名当作实参传给另一个函数(在不修改被装饰函数的情况下,为其添加新功能)
b.返回值中包含函数名(不修改函数的调用方式)
<3>嵌套函数
高阶函数 + 嵌套函数 ==》 装饰器
4.下面举例分析: <1>把一个函数名当作实参传给另一个函数
import time
#把一个函数名当作实参传给另一个函数
def hyt():
time.sleep(3) #延迟三秒
print('This is hyt') def congcong(func): #函数作为变量
str_time = time.time() #记录开始时间
func() #运行hyt函数
stop_time = time.time() #记录结束时间
print('The func runs time is %s '%(stop_time-str_time)) #输出:The func runs time is 3.000171661376953 congcong(hyt)
<2>返回值中包含函数名
import time
#返回值中包含函数名(不修改函数的调用方式)
def hyt():
time.sleep(3) #延迟三秒
print('This is hyt') def cc(func):
print(func)#打印hyt函数的内存地址,结果:<function hyt at 0x00206780>
return func #返回hyt函数的内存地址
hyt=cc(hyt) #cc(hyt)表示传递hyt函数的内存地址,而cc(hyt())表示传递hyt函数的返回值,不符合高阶函数的定义
hyt() #运行hyt函数
<3>嵌套函数
def foo():
# '嵌套函数:在一个函数的函数体内部用def声明并调用另一个函数。'
print('This is foo')
def func(): #局部起作用,故只能在函数体内部调用
print('This is func') func()
foo()
<4>#局部作用域与全局作用域的访问顺序
5.装饰器实际运用
<1>简单点的:
def timer(func): #timer(cc1) func = cc1
'decorator(装饰器高潮版)'
def hyt(*args,**kwargs): #非固定传参,前者接受位置参数,后者接受关键字参数
star_time = time.time() #time.time()调用时间的计时功能
func(*args,**kwargs) #run cc1()
stop_time = time.time()
print('The func running time is %s'%(stop_time-star_time))
return hyt
@timer #等同于cc1 = timer(cc1)
def cc1():
time.sleep(1)
print('This is cc1..')
cc1() @timer #等同于cc2 = timer(cc2) = hyt cc2()=>hyt() ==> cc2(name,age)==>hyt(name.age)
def cc2(name,age):
time.sleep(3)
print('Name is \033[32;1m{s1}\033[0m,Age is \033[31;1m{s2}\033[0m'.format(s1=name,s2=age))
cc2('SC',20)
<2>复杂点的:
#装饰器经典款
import time
user = 'cc'
passwd = ''
def auth(func):
def wrapper(*args,**kwargs):
usename = input('Usename:').strip()
password = input('Password:').strip()
if user == usename and passwd == password:
print('Welcome \033[32;1m%s hased passed authentication\033[0m'%(usename))
func(*args,**kwargs)
else:
exit('\033[31;1m Your usename or password is invalid\033[0m')
return wrapper def index():
print('Welcome index page')
@auth
def home():
print('Welcome home page')
@auth
def bbs():
print('Welcome bbs page')
index()
home()
bbs()
''' #装饰器限量版
import time
user,passwd = 'cc','123456'
def auth(auth_type):
print('Auth type:',auth_type)
#按照登录方式的不同而选择不同的认证方式
def out_wrapper(func):
def wrapper(*args,**kwargs):
usename = input('Usename:').strip()
password = input('Password:').strip()
if auth_type == 'local':
if user == usename and passwd == password:
print('\033[32;1mWelcome %s hased passed authentication\033[0m'%(usename))
res_home = func(*args,**kwargs)# from home
print('---after authentication---')
else:
exit('\033[31;1m Your usename or password is invalid\033[0m')
else:
print('There is no ladp.....')
return wrapper
return out_wrapper def index():
print('Welcome index page') @auth(auth_type='local') #home = home(out_wrapper) => wrapper => home()=>wrapper()
def home():
print('Welcome home page')
return 'from home' @auth(auth_type='ldap')
def bbs():
print('Welcome bbs page')
index()
home()
bbs()
二、生成器(generator) 1.定义:
通过列表生成式。可以直接创建一个列表。但是受到内存限制,列表容量有限。而且,创建一个包含上百万 个元素的列表,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表可以按照某种算法推算出来,那 我们可以在循环的过程中不断推算后续的元素,这样就不必创建完整的list,从而节省大量的空间。在python中, 这种一边循环一边计算的机制,称为生成器:generator。 2.生成器创建方法及实例
<1>最简单的生成方法:把列表生成式的[]改成(),就创建了一个生成器(generator)。 <2>列表生成式和生成器实例:
#列表生成式(简洁) a = [i*2 for i in range(8)]
print(a) #输出结果:[0, 2, 4, 6, 8, 10, 12, 14] #传统的列表生成方式 a = []
for i in range(8):
a.append(i*2)
print(a) #输出结果:[0, 2, 4, 6, 8, 10, 12, 14]
(列表生成式)
L = [x * x for x in range(8)] #列表(list)
print(L) #输出:[0, 1, 4, 9, 16, 25, 36, 49]
M = (x * x for x in range(8)) #生成器(generator)
print(M) #输出:<generator object <genexpr> at 0x00537F00>
print(M.__next__()) #输出:0 生成器的_next_()方法
print(M.__next__()) #输出:1
print(M.__next__()) #输出:4
(生成器)
<3>生成器的调用和迭代
注意:生成器(generator)保存的是算法,每次调用_next_(),就计算出M的下一个元素的值,直到计算到最 后一个元素,没有更多元素时,抛出StopIteration(异常)的错误。但这种方法太过繁琐,创建generator后, 基本不会使用_next_(),正确方法是使用for循环来迭代它,并且不需要关心StopIteration的错误
N = (y*2 for y in range(6))
for i in N:
print(i) #输出:0 2 4 6 8 10
<4>斐波拉契数列和异常处理
generator很强大,但如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以使用 函数来实现。比如著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数可有前两个数相加得 到:1,1,2,3,5,8,13,...斐波拉契数列用列表生成式写不出来,但可用函数轻松表示出来
def fib(max): #max = 10
n ,a,b = 0,0,1
while n < max:
#print(b)
yield b #yield 表示出产,产生,保存了函数的中断状态
a,b = b,a+b # t = (b,a+b) 是一个元组,a=t[0],b=t[1]
n = n + 1
return 'worked down' #异常的时候打印return的内容
#fib(10) #输出:1,1,2,3,5,8,13,21,34,55
print(fib(max)) #输出:<generator object fib at 0x00507E70> '''
f = fib(10)
print(f.__next__())#输出:1
print(f.__next__())#输出:1
print(f.__next__())#输出:2
print('Hello everyone,now looping') #可以插在生成器其中不影响其连续过程
for i in f:
print(i)#输出:3,5,8,13,21,34,55
'''
#异常处理
g = fib(6)
while True:
try: #未出错的时候执行
x = next(g) #next为内置方法,等同于_next_()方法
print('g:',x) #输出:g: 1 1 2 3 5 8
except StopIteration as e: #出错时捕获错误定义为e
print('Generator return value:',e.value) #输出Generator return value: worked down
break
3.关于生成器并行运算
import time
def consumer(name):
print('\033[32;1m%s\033[0m 准备吃饭了'%name)
while True:
shuijiao = yield #yield 接受来自N的send 方法传来的参数
print('\033[31;1m[%s]\033[0m 饺子煮好了,被\033[32;1m%s\033[0m吃完了'%(shuijiao,name)) N = consumer('hyt')
N.__next__() #此方法只调用,不传值,输出:hyt 准备吃饭了
N.__next__() #输出:[None] 饺子煮好了,被hyt吃完了
b1,b2 = '猪肉馅','牛肉馅'
N.send(b1) #send方法调用并传值,输出:[猪肉馅] 饺子煮好了,被hyt吃完了
N.send(b2) #输出:[牛肉馅] 饺子煮好了,被hyt吃完了 def prodouct(name):
c1 = consumer('sc')
c2 = consumer('cc')
c1.__next__()
c2.__next__()
print('\033[32;1m%s 开始做饺子了!\033[0m'%name)
for i in range(3):
time.sleep(2)
print('两人平分一碗饺子')
c1.send('粉丝')
c2.send('韭菜')
prodouct('congcong')
三、迭代器
1.可迭代对象(Iterable)
<1>定义:
可以直接作用于for循环的数据类型有以下几种:
一类 是集合数据类型,如list、tuple、dict、set、str等
二类 是generator,包括生成器和带yield的generator function.
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
<2>判断方法:可以使用isinstance()判断一个对象是否有Iterable对象。
<3>实例:
from collections import Iterable
print(isinstance([],Iterable)) #判断列表是否有可迭代对象 True
print(isinstance((),Iterable)) #判断字典是否有可迭代对象 True
print(isinstance({},Iterable)) #判断集合是否有可迭代对象 True
print(isinstance('huangyuting',Iterable)) #判断字符串是否有可迭代对象 True
print(isinstance(666,Iterable)) #判断数字是否有可迭代对象 False
print(isinstance((x for x in range(4)),Iterable)) #判断generator是否有可迭代对象 True
注意:而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,
直到最后抛出StopIteration错误表示无法继续返回下一个值了。
2.迭代器(Iterator)
<1>定义:可以被next函数调用并不断返回下一个值的对象称为迭代器:Iterator。
<2>判断方法:可以使用isinstance()判断一个对象是否是迭代器(Iterator)对象。
<3>实例:
from collections import Iterator
print(isinstance((),Iterator)) #判断字典是否是迭代器 False
print(isinstance([],Iterator)) #判断列表是否是迭代器 False
print(isinstance({},Iterator)) #判断集合是否是迭代器 False
print(isinstance('congcong',Iterator)) #判断字符串是否是迭代器 False
print(isinstance(888,Iterator)) #判断数字是否是迭代器 False
print(isinstance((x for x in range(5)),Iterator)) #判断生成器是否是迭代器 True
<4> 可迭代对象转成迭代器的方法:
由上可知,生成器都是迭代器,然而list,dict,str虽然都是可迭代对象(Iterable),但不是
迭代器(Iterator),可以把list,dict,str等Iterable变成Iterator可以使用iter()函数。如下
所示:
from collections import Iterator
print(isinstance(iter([]),Iterator),type(iter([]))) #True <class 'list_iterator'>
print(isinstance(iter(()),Iterator),type(iter(()))) #True <class 'tuple_iterator'>
print(isinstance(iter({}),Iterator),type(iter({}))) #True <class 'dict_keyiterator'>
print(isinstance(iter('hytsc'),Iterator),type(iter('hytsc'))) #True <class 'str_iterator'>
3.一点疑问解答: 为什么list,dict,str等数据类型不是迭代器(Iterator)?
因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopItration错误。可以将这个数据流看成一个有序序列,但我们却不能提前知道序列的长度,只有不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
4. Python的for循环本质上就是通过不断调用next()函数实现的,
例如:
for x in range(5):
print(x)
#等价于
t = iter(range(5)) #首先获得Iterator对象
#print(dir(t)) #打印 t 可调用的所有方法
while True: #循环
try:
x = next(t) #获取下一个值
except StopIteration: #遇到StopIteration就退出循环
break
四、python内置函数大揭秘:
print(all([1,0,4])) #所有数据为真(非零即为真),空表也为假 输出:False
print(any((0,-1,4))) #任意数据为真 输出:True
print(bin(10)) #将十进制转为二进制 输出:0b1010
print(hex(10))#将十进制转为十六进制 输出:0xa
print(oct(8))#将十进制转为八进制 输出:0o10
print(bool([])) #判断真假(非零即为真),输出:False a = bytes('abcde',encoding='utf-8')
print(a) #输出:b'abcde'
b = bytearray('abcde',encoding='utf-8')
print(b) #输出:bytearray(b'abcde')
b[0] = 65 #此处只能输入ASCII码值,A为97
print(b) #输出:bytearray(b'Abcde') a = 'hello'
print(a.capitalize(),a) #字符串不能修改,只能重新生成新的,输出:Hello hello def func():
pass
print(callable(func)) #判断是否可调用 print(chr(97)) #打印ASCII码对应的字符,输出;a
print(ord('a')) #打印字符a对应的ASCII码值,输出;97 code = '''
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 'worked down'
#fib(10)
#异常处理
g = fib(10)
while True:
try: #未出错的时候执行
x = next(g) #next为内置方法,等同于_next_()方法
print('g:',x) #输出:g: 1 1 2 3 5 8
except StopIteration as e: #出错时捕获错误定义为e
print('Generator return value:',e.value) #输出Generator return value: worked down
break
'''
exec(code) #将字符串编译成一段可执行文件
#py_obj = compile(code,"fib.log","exec") #将字符串编译成指定文件名的可执行代码
#exec(py_obj) print(dir(code)) #打印 字符串code的所有方法
print(divmod(9,2)) #求两个数的商和余数,并打印出来,输出:(4, 1) h = "['hello','world']"
print(eval(h)) #将字符串转成字典或列表 calc = lambda n:n**2
print(calc(3))
calc = lambda n:4 if n<3 else n #lambda为匿名函数
print(calc(2)) #输出:4 res = filter(lambda x:(x%2==1),range(10)) #从列表中筛选0到100以内的奇数
for i in res:
print(i) #输出:1,3,5,7,9 res1 = map(lambda y:y*2,range(4))#将列表中元素全部处理
res2 = [lambda d:d*d for d in range(2)]
for i in res1:
print(i)#输出:0,2,4,6
for i in res2:
print(i)#输出:<function <listcomp>.<lambda> at 0x006BE4F8>
# <function <listcomp>.<lambda> at 0x002EE300> import functools #functools意为函数工具
res3 = functools.reduce(lambda a,b:a*b ,range(1,6))#求列表1到6的阶乘,a接收a*b的值,b接收列表中的值
print(res3)
(待续)
a = frozenset([1,2,3,5,6,8]) #frozenset函数修饰后为不可变列表,集合 print(globals()) #打印所在模块当前最大命名空间内的变量名和值(key-value)
print(hash('cc'))#哈希函数,建立字符串等于数字的特定位置关系,输出:1362460451 def test():
local_test = 666 #局部变量
print(locals())#返回局部变量,输出:{'local_test': 666} 打印所在模块当前最小命名空间内的变量名和值
print(globals())#不包含local_test
test()
b = 999
print(globals()) #只打印全局变量,不打印局部变量
print(globals().get('local_test')) #输出:None print(pow(2,4)) #表示求 2 的 4 次方 输出:16 print(round(3.14159,2)) #表示将3.14159保留两位小数
'''
a = {'b':5,'a':1,'d':4,'c':8}
print(sorted(a.items())) #输出:[('a', 1), ('b', 5), ('c', 8), ('d', 4)],默认以key排序
print(sorted(a.items(),key=lambda x:x[1] ))#输出:[('a', 1), ('d', 4), ('b', 5), ('c', 8)],指定以value排序 d = [1,3,5,7]
e = ['h','e','l','l','o']
for i in zip(d,e): #zip取最短的列表进行一一对应
print(i) #输出:(1, 'h') (3, 'e') (5, 'l') (7, 'l') __import__('生成器') #导入字符串
(完结)
五、序列化与反序列化
<1>序列化(json、pickle)
#序列化:将内存对象转换成字符串保存起来
'''import json
info = {
'name':'cc',
'age':20,
'job':'student'
}
f = open('test.txt','w',encoding='utf-8')
#f.write(str(info))#很low的方法
print(json.dumps(info),type(json.dumps(info)))#输出:{"age": 20, "job": "student", "name": "cc"} <class 'str'>
f.write(json.dumps(info)) #专业方法
f.close()
'''
#json 与 pickle 的区别在于:pickle只能在python中使用,而json却可以在各个语言间转换 #pickle
import pickle
def hey(name):
print('hello',name) info2 = {
'name':'hyt',
'age':18,
'func':hey
}
f = open('test2.txt','wb')
print(pickle.dump(info2,f))#输出:None
pickle.dump(info2,f) #与 f.write(pickle.dumps(info)) 作用相同
f.close()
<2>反序列化(json、pickle)
import json
f = open('test.txt','r')
#很low的方法
data = f.read()
f.close()
print(data,type(data)) #输出:{'age': 20, 'job': 'student', 'name': 'cc'} <class 'str'>
print(eval(data),type(eval(data))) #eval()是内置函数,可将字符串转为字典或列表,
#输出:{'name': 'cc', 'age': 20, 'job': 'student'} <class 'dict'
#专业的方法
data = json.loads(f.read())
print(data,type(data))#输出:{'job': 'student', 'age': 20, 'name': 'cc'} <class 'dict'>
print(data['name'])#输出:cc
''' #pickle
import pickle
def hey(name):
print('hello',name)
info2 = {
'name':'hyt',
'age':18,
'func':hey
}
f = open('test2.txt','rb')
data = pickle.load(f)# data = pickle.loads(f.read())
print(data,type(data)) #输出:{'age': 18, 'name': 'hyt', 'func': <function hey at 0x0094E468>} <class 'dict'>
print(data['func']('hyt'))
f.close()
Python初识 - day5的更多相关文章
- python笔记 - day5
python笔记 - day5 参考: http://www.cnblogs.com/wupeiqi/articles/5484747.html http://www.cnblogs.com/alex ...
- Python学习day5作业
目录 Python学习day5作业 ATM和购物商城 1. 程序说明 2. 基本流程图 3. 程序测试帐号 4. 程序结构: 5. 程序测试 title: Python学习day5作业 tags: p ...
- python初识(二)
目录: 进制 基本数据类型 整形 布尔值 字符串 列表 元祖 字典 集合 range & enumerate 一.进制 二进制转换十进制计算: 十进制:==47 一个字节公式:==128 64 ...
- 小学生绞尽脑汁也学不会的python(初识面对对象)
小学生绞尽脑汁也学不会的python(初识面对对象) 一. 面向对象思想 1. 面向过程. 重点在"过程". 按照实物的发展流程. 先干嘛,后干嘛, 最后干嘛.... 优点: 简单 ...
- Python 入门【一】Python 初识及学习资料
Python 初识及学习路线: CodeCademy Python 在线教学: 廖雪峰 Python 2.7 教程: 廖雪峰 Python 3.0 教程: Python 官方文档(2.7~3.7:英文 ...
- Python初识类与对象
Python初识类与对象 类与对象 世界观角度分析类与对象 类是一个抽象的概念,而对象是一个实体的存在,对象由类创造而出,每个对象之间互相独立互不影响,一个对象可以同时拥有多个类的方法,实例化就是通过 ...
- Python初识函数
Python初识函数 函数理论篇 什么是函数 在编程语言中的函数不同于数学中的函数.不管是数学上的函数还是编程语言中的函数都是为了完成特定的某一功能而诞生的,他们的区别在于: 1.数学中的函数当输入的 ...
- Python初识与简介【开篇】
目录 1.扯淡 2.Python历史 3.Python简介 4.Python应用 5.为什么是python而不是其他语言? 6.Python的种类 7.Python的特点 8.Python设计哲学 9 ...
- Python初识文本基本操作
初识文本的基本操作 怎么在文件里面写内容和都内容 文件操作过程 1,找到文件 文件路径 2,打开文件 file_obj=file(文件路径,模式) 3,文件操作,读写文件 file_obj.read( ...
随机推荐
- IOS10.3上传照片只能拍照不能选择解决办法
升级IOS10.3正式版以后可能会出现上传文件的控件只能拍照而不能选择现有图片的问题. 正好被我们碰到了,于是找了找解决思路,发现如下解决思路: 原代码为: <input type=" ...
- 微信支付接口开发之---微信支付之JSSDK(公众号支付)步骤
1.准备 1.1.公众号为服务号,开通微信支付功能 1.2.为了方便调试微信后台的回调URL(必须为外网),我用了nat123软件来做一个映射 1.3.官方微信开发的示例WxP ...
- python 命令
pip list 可以查看已经安装的插件 pip show name 可以查看插件的信息(如:pip show selenium) pip install selenium==[version num ...
- js 前端操作的分页路由设计
//分页条获得分页数字,然后跳转到拼接字符串的页面 function getPage(page) { var window_href = location.pathname; var newWindo ...
- IdentityServer Topics(4)- 登录
为了使IdentityServer代表用户发布令牌,该用户必须登录到IdentityServer. Cookie认证 使用来自ASP.NET Core的cookie身份验证处理程序管理的cookie跟 ...
- Elastic Stack之kibana入门
为了解决公司的项目在集群环境下查找日志不便的问题,我在做过简单调研后,选用Elastic公司的Elastic Stack产品作为我们的日志收集,存储,分析工具. Elastic Stack是ELK(E ...
- 关于构造函数和原型prototype对象的理解
构造函数 1.什么是构造函数 构造函数,主要用于对象创建的初始化,和new运算符一起用于创建对象,一个类可以有多个构造函数,因为函数名相同,所以只能通过参数的个数和类型不同进行区分,即构造函数 ...
- ubuntu16中遇到libgstreamer-0.10.so.0缺失解决方案
1. error while loading shared libraries: libgstreamer-0.10.so.0: cannot open shared object file: No ...
- SQL server学习(二)表结构操作、SQL函数、高级查询
数据库查询的基本格式为: select ----输出(显示)你要查询出来的值 from -----查询的依据 where -----筛选条件(对依据(数据库中存在的表)) group by ----- ...
- 信息学奥赛一本通算法(C++版)基础算法:高精度计算
高精度加法(大位相加) #include <bits/stdc++.h> using namespace std; int main() { ],b1[]; ],b[],c[];//a,b ...