一、装饰器(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的更多相关文章

  1. python笔记 - day5

    python笔记 - day5 参考: http://www.cnblogs.com/wupeiqi/articles/5484747.html http://www.cnblogs.com/alex ...

  2. Python学习day5作业

    目录 Python学习day5作业 ATM和购物商城 1. 程序说明 2. 基本流程图 3. 程序测试帐号 4. 程序结构: 5. 程序测试 title: Python学习day5作业 tags: p ...

  3. python初识(二)

    目录: 进制 基本数据类型 整形 布尔值 字符串 列表 元祖 字典 集合 range & enumerate 一.进制 二进制转换十进制计算: 十进制:==47 一个字节公式:==128 64 ...

  4. 小学生绞尽脑汁也学不会的python(初识面对对象)

    小学生绞尽脑汁也学不会的python(初识面对对象) 一. 面向对象思想 1. 面向过程. 重点在"过程". 按照实物的发展流程. 先干嘛,后干嘛, 最后干嘛.... 优点: 简单 ...

  5. Python 入门【一】Python 初识及学习资料

    Python 初识及学习路线: CodeCademy Python 在线教学: 廖雪峰 Python 2.7 教程: 廖雪峰 Python 3.0 教程: Python 官方文档(2.7~3.7:英文 ...

  6. Python初识类与对象

    Python初识类与对象 类与对象 世界观角度分析类与对象 类是一个抽象的概念,而对象是一个实体的存在,对象由类创造而出,每个对象之间互相独立互不影响,一个对象可以同时拥有多个类的方法,实例化就是通过 ...

  7. Python初识函数

    Python初识函数 函数理论篇 什么是函数 在编程语言中的函数不同于数学中的函数.不管是数学上的函数还是编程语言中的函数都是为了完成特定的某一功能而诞生的,他们的区别在于: 1.数学中的函数当输入的 ...

  8. Python初识与简介【开篇】

    目录 1.扯淡 2.Python历史 3.Python简介 4.Python应用 5.为什么是python而不是其他语言? 6.Python的种类 7.Python的特点 8.Python设计哲学 9 ...

  9. Python初识文本基本操作

    初识文本的基本操作 怎么在文件里面写内容和都内容 文件操作过程 1,找到文件 文件路径 2,打开文件 file_obj=file(文件路径,模式) 3,文件操作,读写文件 file_obj.read( ...

随机推荐

  1. chrome调试工具高级不完整使用指南(优化篇)

    上一篇文章我们说了chrome调试工具的一些比较基础功能的用法,接下来我们要在这一篇文章中说一说,其他一些chrome调试工具的使用方法 2.1.5 Network模块 在netWork模块中,大致上 ...

  2. C++\virtual 虚函数、纯虚函数

    前提摘要: 虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 虚函数定义: 指向基类的指针或引用在操作它的多态类(子类/派生类)对象时,会根据不同的类对象, ...

  3. swift中的AnyHashable

    AnyHashable是调和objc和Swift的产物 典型的场景是,objc下无泛型的NSDictionary到了Swift下,会变成什么?(典型例子是苹果来的推送消息) [Any: Any],这肯 ...

  4. python3之File文件方法

    1.读写文件 open()将会返回一个file对象,基本语法: open(filename,mode) filename:是一个包含了访问的文件名称的路径字符串 mode:决定了打开文件的模式:只读, ...

  5. Label 和 checkbox 不为人知的小秘密

    最近开发的时候同事遇见了一个问题,点击label的时候改变checkbox的属性,或许大家觉得这是一个很简单的问题,然而这里面却蕴藏着一个大坑! 举例说明: 页面简单,就是一个 <input i ...

  6. for循环相关的一个问题

    首先,我在for循环外定义了两个变量. //在4条直线方向,获取预置点两端的8个点的棋盘信息 ,r=,c=;//step代表直线,r,c分别代表加上偏移量之后的坐标 ,myCount=,hisCoun ...

  7. JAXB应用实例

    过往的项目中数据存储都离不开数据库,不过最近做的一个项目的某些数据(比如人员信息.菜单.权限等等)却完全没有涉及任何数据库操作,直接XML搞定.这里无意比较优劣,因为数据库存储和XML存储本就有不同的 ...

  8. “玲珑杯”ACM比赛 Round #13 题解&源码

    A 题目链接:http://www.ifrog.cc/acm/problem/1111 分析:容易发现本题就是排序不等式, 将A数组与B数组分别排序之后, 答案即N∑i=1Ai×Bi 此题有坑,反正据 ...

  9. bzoj:1687;poj 2434:[Usaco2005 Open]Navigating the City 城市交通

    Description A dip in the milk market has forced the cows to move to the city. The only employment av ...

  10. qsc oj 22 哗啦啦村的刁难(3)(随机数,神题)

    哗啦啦村的刁难(3) 发布时间: 2017年2月28日 20:00   最后更新: 2017年2月28日 20:01   时间限制: 1000ms   内存限制: 128M 描述 哗啦啦村作为喵哈哈村 ...