Python之路-4
1.1 装饰器、生成器、迭代器、调用函数、内置函数
1.1.1 装饰器
装饰器:本质势函数,(装饰其它函数)就是为其他函数添加附加功能。
原则:1、不能修改被被装饰的函数的源代码
2、不能修改被装饰的函数的调用方式
实现装饰器的知识储备:
1、函数即“变量”
2、高阶函数
3、嵌套函数
高阶函数 + 嵌套函数 = 装饰器
下面举个列子:
【高级版】
import time #申明库 def timer(func): #定义timer函数 def deco(*args,**kwargs): #定义deco函数,(嵌套函数) start_time = time.time() #获取func函数开始的时间 func(*args,**kwargs) #执行func函数 stop_time = time.time() #获取func函数结束的时间 print('the func run time is %s'%(stop_time-start_time)) #打印func函数执行的总时间 return deco #在timer函数中返回deco地址变量 @timer #装饰器 #test = timer(test) def test(): time.sleep(3) print('in the test') test()
【终极版】
# -*- coding:utf-8 -*- #!/usr/bin/env python # Author:suchagal username = 'xuwei' password = 'suchagal' def auth(auth_type): def outer_wrapper(func): def wrapper(*args, **kwargs): if auth_type == 'local': users = input('input username:').strip() passwd = input('input passwd:').strip() if users == username and passwd == password: res = func(*args, **kwargs) print('\033[32;1mwelcome to home\033[0m') return res else: exit('\033[31;1minvalid input\033[0m') elif auth_type == 'ldap': print('什么ldap,我不会。。。') return wrapper return outer_wrapper @auth(auth_type = 'local') #home = auth(home) def home(name): print('i am home',name) return 'xuwei' @auth(auth_type = 'ldap') def bbs(): print('i am bbs') home('daweige') bbs()
这个装饰器的目的是提供不同的认证方式,可以再本地认认证们也可以在远端认证LDAP认证。装饰器传进去的参数的不同,来进行认证。
个人理解:装饰器本质就是将被装饰的函数“门牌号”传递给另一个函数的“门牌号”,然后通过修改该函数体来改变函数,最后再将“门牌号”传递回来。
1.1.2 调用函数
调用Python中的定义的函数(也就是不需要import就可以直接用的函数),可以在任何地方调用。
还有调用一些函数时是需要import的,这个应该是对应组件中的函数,比如:import re就可以调用正则函数;import sys就可以调用系统对应的函数;import os就可以调用目录结构的相关函数;import time就可以调用系统时间的相关函数;import copy就可以实现深copy(见5.1.7)。
调用自己写的函数,分为两种情况(目前我所知道的,知增录扩)
1、在相同的Python文件目录下
直接import Python的文件名,然后文件名.方法名();
2、在不同的Python文件目录下
先要添加上层目录地址,再from xxx import xxx;如下:
import os import sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from conf import settings from core import main
1.1.3 生成器
列表生成器:
[i*2 for i in rangae(10)]
>>>[0 2 4 6 8 10 12 14 16 18]
原理:列表生成器在没有执行之前是“门牌号”储存在计算机内存中的,也就是说在计算机内存中不是“[0 2 4….]”。这样可以省内存!
再举个例子:
# -*- coding:utf-8 -*- #!/usr/bin/env python # Author:suchagal import time def consumer(name): print('%s 准备吃包子啦!' %name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def productor(prod_name): c = consumer('小明') c1 = consumer('小小明') c.__next__() #执行一次consumer()函数 c1.__next__() #同上 print("\033[31;1m%s开始做包子了!\033[0m" %prod_name) weidao = ['韭菜','大白菜','猪肉','牛肉','羊肉','空心菜','榨菜','小白菜','鸭肉','鸡肉'] for i in weidao: time.sleep(1) print("做了两个包子") c.send(i) #将weidao发送给baozi c1.send(i) #同上 productor("小明")
上面的函数可以在单线线程下执行多线程的效果,这个就是nginx单线程会比其他多线程还要快几倍的原因!
1.1.4 迭代器
我们已经知道,可以直接作用于for循环的数类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:iterable。
*可以使用isinstance()判断一个对象是否是iterable(迭代器)对象:
而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,知道最后抛出stopiteration异常错误表示无法集训返回下一个值。
可以被next()函数调用并不断返回下一个值的对象成为迭代器。
生成器一定是迭代器,迭代器不一定是生成器。
1.1.5 内置函数
print(abs(-7)) #取绝对值 print(all([1,2,3,4])) #列表中的元素都为真返回true,有一个为假则返回false print(any([0,0,0])) #列表中的元素都为假返回false,至少有一个则返回true a = ascii([1,2,'xuwei','suchagal']) #将一个列表,字典,变成字符 print(type(a),[a]) b = eval('''[1,2,'xuwei','suchagal']''') #取注释 print(b[2]) print(bin(34)) #十进制转二进制 print(bool(1)) #判断真假,也可以判断列表 print(bool([])) a = bytes('abcde',encoding='utf-8') #str不可以修改 print(a.capitalize(),a) b = bytearray('abcde',encoding='utf-8') #可以修改str print(b[1]) b[1] = 101 print(b) def ssaf():pass print(callable(ssaf)) #可以调用返回true,不可调用返回false print(chr(98)) #返回数字在ASCII码中对应的str print(ord('b')) #返回ASCII中的str对应的数字 compile() #将一串字符串代码执行(忘记它吧,没什么卵用) exec() #可以将一个被注释的程序执行 eval() #去掉注释,并执行,被注释的部分非程序 dir() #查看该类,字典有什么方法 dict(a=b,c=3) #生成一个字典 divmod(5,3) #返回一个5/3=(1,2) res = filter(lambda n:n*n,range(10)) for i in res: print(i) sas = map(lambda n:n*2,range(10)) #将后面range的值传个lambda处理,处理完了传给map for ii in sas: print(ii) print(sas) import functools res = functools.reduce(lambda x,y:x+y,range(10)) print(res) a = frozenset([12,3,23,34,3,45,22,22]) #让集合没有怎删改查的选项 print(globals()) #显示出当前文件中的全局变量(字典类型) print(locals()) #打印局部变量 print(hex(3234)) #将一个数字转成16进制
The unexamined life is not worth living.--Socrates
浑浑噩噩的生活不值得过.
                    
                
                
            
        
浙公网安备 33010602011771号