装饰器及模块

装饰器(难):
函数里面可以再嵌套一个函数
高阶函数
说白了就是函数嵌套+高阶函数
装饰器的作用就是在不改变原有函数的调用方式,入参的情况下,给函数添加新功能
偷偷摸摸的给函数加上新功能,但是不改变原来的函数

1)函数嵌套函数:
def a():
print(‘1‘)
def b():
print(‘2‘)
def c():
print(‘3‘)
a()
上述,b和c函数只有定义,没有执行,所以只会执行最外面的a函数,如果在每层def之后依次执行abc函数,则会输出‘1’‘2’‘3’

2)函数的作用域,就近原则,自己函数里有,就拿过来用,如果没有就去父级函数里面找

本级找不到变量name的话,自动取上一级(从里往外找),但是父级不可用子级的变量值
输出的值,不是根据print的顺序,是根据函数调用的顺序,必须得调用才能执行。

以上,a在调用后,先从name = ‘1’ 开始,然后b函数开始定义,在b执行之后,里面的内容才开始执行,从name=‘2’ 开始,先遇到了print(‘b的name是%s‘ % name),所以先输出,之后在c定义之后,先遇到了c执行,所以第二条是print(‘c的name是%s‘%name),最后才是print(‘a的name是%s‘%name)

原式子:

改进后的:

上图可以,但是对比之前的,run函数的调用已经从run()变更为run_time(run),调用方式改变了。

要完全实现装饰器的内容(标红部分是个装饰器),可以按下述条件来写:
import time
def run():
print(‘running‘)
time.sleep(1)
def timer(func):
def deco():
start_time = time.time() # 开始时间
func()#deco函数里面没有func这个函数,父级入参了func变量,子集取过来执行
end_time = time.time() # 结束时间
print(‘run函数运行是‘,end_time-start_time)
return deco#timer函数返回了一个函数名,这个函数存的是上面deco那段代码,deco未调用,没执行,此时什么都不会返回
run = timer(run) #run== deco,这里的run可以换成别的名字,包括改成deco或者其他值,只是一个变量名,如果换成run相当于替换了run里面的代码
#调用timer函数的时候,要传入一个方法名
# timer函数在函数内部定义了一个函数叫做deco
#又在deco函数内部调用了timer里面传入的方法
#run存的是deco,deco是一个函数,调用run就是调用deco
run()#deco是一个局部变量,但是run在返回后还有定义,所以run可以执行
#如果后续还有调用run的地方,就是在当前功能的基础上再添加代码,一直添加下去了。

上述式子改变格式:
import time
def timer(func):
def deco(*args,**kwargs):
start_time = time.time() # 开始时间
res = func(*args,**kwargs)#deco函数里面没有func这个函数,父级入参了func变量,子集取过来执行;func里面加上俩形参,用来接收传入函数的参数,完善逻辑
end_time = time.time() # 结束时间
print(‘runtime‘,end_time-start_time)
return res#防止函数有返回值接收不到,再加一个获取返回值
return deco
@timer #和“run = timer(run)” 意思相同,写在timer()定义的后面
def run():
print(‘running‘)
time.sleep(1)
run()#也可以去掉@timer,直接写成timer(run)(),会得到相同结果,但是这样写就改变原有调用方式了
@timer#装饰器可以在多个函数中用,谁需要在定义前加上即可
def run2(name):#run2里面传入了参数name时,上面的deco()定义里面如果不同步设置一个形参,就会报错。
print(name)
time.sleep(0.5)
run2(‘niuhanyang‘)
run()

内置函数:(标黑才是常用,其他知道即可)

print(all([1,2,3,4]))#判断可迭代的对象里面的值是否都为真
print(any([0,1,2,3,4]))#判断可迭代的对象里面的值是否有一个为真
print(bin(10))#十进制转二进制
print(bool(‘s‘))#把一个对象转换成布尔类型,还有int() float() str() dict() list() set() tuple(),元组值不能变,列表能变
print(callable(‘aa‘))#判断传入的对象是否可调用
print(chr(10))#打印数字对应的ascii
print(ord(‘b‘))#打印字符串对应的ascii码
print(dict(a=1,b=2))#转换字典
print(dir(1))#打印传入对象的可调用方法,带下划线的不用管
print(eval(‘[]‘))#执行python代码,只能执行简单的,定义数据类型和运算,引号里面可以换成字典{}\list[]\字符串等等
print(exec(‘def a():pass‘))#执行python代码
filter(func,[1,2,3,4])#根据前面的函数处理逻辑,依次处理后面可迭代对象里面的每个元素,返回true才保存,不适用于多个入参
【举例】
def func(num):
return num
print(filter(func,[0,1,2,3,4]))#在python2里面会返回[1,2,3,4],python3只会返回内存地址
print(list(filter(func,[0,1,2,3,4])))#非0即真,在python3里面返回[1,2,3,4]

map(func,[1,2,3,4])#根据前面的函数处理逻辑,依次处理后面可迭代对象里面的每个元素,保存前面函数返回的所有结果,上述例子换成map返回[0,1,2,3,4]
print(globals())#返回程序内所有的变量,返回的是一个字典,函数里面的局部变量不会返回
print(locals())#在函数体里面用,返回这个函数所有的局部变量
print(hex(111))#数字转成16进制
print(max(111,12))#取最大值,也可以传列表
print(oct(111))#把数字转换成8进制
print(round(11.1198,2))#取几位小数,会四舍五入,返回11.12
print(sorted([2,31,34,6,1,23,4]))#排序,默认是升序,加上reverse=True表降序,
【举例】
dic={1:2,3:4,5:6,7:8}
print(sorted(dic.items()))#按照字典的key排序

print(sorted(dic.items(),key=lambda x:x[1]))#按照字典的value排序
__import__(‘decorator‘)#导入一个模块

常用模块
http://www.nnzhp.cn/blog/2016/12/19/python%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E5%85%AD%E5%B8%B8%E7%94%A8%E6%A8%A1%E5%9D%97/
什么是模块,模块其实就是一个python文件,常见的os,time,sys 在pycham里面ctrl+单击名称,即可以查看模块内部写法
用哪个模块就要import哪个模块,格式:import+python文件名(不要.py后缀)
import的本质就是把这个python从头到尾执行一次
如:两个python文件a.py和b.py如果要在a中定义了一个函数run(),在b中写
import a
a.run()#这里一样会执行a这个函数,a中定义多个,这里也可以调用多个,格式--模块名.函数()

如果a中有多个函数,b中不想全部import,那么可以写成如下:
from a import run,run1#只导入某个函数的时候这么写,但是代码也会从头到尾执行一遍,只是最后保留其中要的函数
run()
run1()

from a import *# 也可以这样写,表示导入a模块中的所有函数
from a1 import *#导入a1模块中的所有函数,多行这种很难识别,自己千万别写!!
run()
run1()
run2()

from day4.a import run#在其他目录下导入,terminal下运行报错,直接run可以(run的时候,会自动把这段代码加到环境变量中,所以可以);如果加到环境变量中(环境变量就是让你在任意一个目录下都可以使用这个命令),那就都可以执行
run()
ps:包和文件夹的区别就是,python2里面,如果要导入其他文件夹下面的python文件,那么文件夹必须是个包(下面带个_init_.py),python3里面不要求,是文件夹就行
导入模块的时候,python首先在当前目录下找这个模块,如果在当前目录下没有找到这个文件的话,那么就去环境变量里面的目录找,都找不到,则报错。
【如何看】
import sys
print(sys.path)#看系统环境变量
sys.path.append(‘E:\byz_code‘)#可以执行该语句将目录加到环境变量里面

避免碰见要应用的py文件和系统常见模块名称一致!如time.py和import time
import random
import random,string
print(random.random())#随机浮点数,默认取0-1,不能指定范围,没啥用
print(random.randint(1,20))#随机整数
print(random.randrange(1,20))#随机产生一个range,基本上和randint一致
print(random.choice(‘x23serw4‘))#随机取一个元素,里面可以是字符串,list等可迭代对象,返回类型无限制
【举例】
date_list = [‘10:23‘,‘10:24‘]
random.choice(date_list)
print(random.sample(‘hello‘,2))#从序列中随机取2个元素,也可以取list等,数字可变,返回的是int
print(random.uniform(1,9))#随机取浮点数,可以指定范围
x = [1,2,3,4,6,7]
random.shuffle(x)#洗牌,打乱顺序,会改变原list的值,只能是list
print(x)#无赋值,不会返回值,直接打乱了x的顺序,x只能是list
print(string.ascii_letters+string.digits)#所有的数字和字母

五、json处理,可以用与字典和list
json格式和字典很像,比如true的首字母大小写,而且json里面只能是双引号,python单双引号都可以,可以用www.bejson.com校验格式
json串实际上就是一个字符串(接口返回的json其实就是个字符串)

如果json是存在文件里面,则用
fr = open(‘users‘)
json_dic_file = json.load(fr)#这里和json.loads(fr.read())一样
#load方法是传入一个文件对象,然后load方法自动去读这个文件的内容,然后转成字典

把字典转成json串并且生成到newuser文件中

只有两种方法:
json.loads()和json.load() : json串转字典的
json.dumps()和json.dump() :字典转json串的
带s的就和字符串沾边,不带s的

时间: 2024-10-11 06:36:37

装饰器及模块的相关文章

python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化

生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: 1 >>> g = (x * x for xin range(10)) 2 >>> g3 <generator object <genexpr> at 0x1022ef630> 此处g就是一个生成器. 迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是gene

python3.5-day5_迭代器_生成器_装饰器_模块

笔者QQ 360212316 迭代器&生成器 生成器: 一个函数调用返回一个迭代器,那这个函数叫做生成器,如果函数中包含yield语法,那么这个函数就会变成生成器 生成器的特点: 1.生成器必须从前往后一次访问,不能跳着取 2.生成器只记录访问的数据,其他数据释放 3.生成器的作用就是预想可能用到那么多的数据 生成器的两种方式: 方式一: data = (x * 2 for x in range(5)) # 获取结果的两种方式 print(data.__next__()) print(next(

python装饰器、模块

python装饰器 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用函数,假设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这

python 培训第三章 ,函数,装饰器,模块,内置函数之一函数

目录: 函数示例装饰器模块内置函数一.函数示例: 1.定义函数: def fun(args): '描述信息' 函数体 return 返回值 定义函数的三种形式: 无参函数def foo():print('in the foo') foo() 有参函数: def bar(x,y): print('in the bar') bar(1,2) 空函数: def func(): pass 空函数的应用示例: def put():pass def get():pass def cd():pass def

第8章 装饰器、模块和包

一 什么是装饰器 二 装饰器需要遵循的原则 三 实现装饰器知识储备 四 高阶函数 五 函数嵌套 六 闭包 七 无参装饰器 八 装饰器应用实例 一 什么是装饰器

Python学习笔记6-python函数补充、装饰器、模块

本文主要学习内容有 函数知识的补充 装饰器(无参.有参.非固定参数.有返回值) 函数知识的补充 稍后待续...

day05 Python多层装饰器、模块、字符串格式化、生成器和迭代器、递归

一.多层装饰器 需求如下:     程序运行时需判断当前是否有用户登录,以及当前登录的用户名是否为管理员账户,但有的函数只需判断当前是否有用户登录就可以,有的函数两个都需要判断,所以将这两个判断分开写成两个装饰器,在需要判断时直接使用相应的一个或两个装饰器即可,具体代码如下: #!/usr/bin/env python # -*- coding:utf-8 -*- #保存当前登录的账户名及账户类型(管理员为2,普通用户为1) USER_INFO = {} def check_login(func

第九节:python pickle序列化、装饰器、模块

python个人笔记,纯属方便查询 中间退出的时候要保存,然后再次进入的时候还是退出的那个点. 字典-----字符串(硬盘)------字典 pickle语法dump: 把字典写入硬盘文件中: import pickle account_info = { 'a':'bbbbbbbbb', 'b':'ccccccccc' } f=file('account.pki','wb')         #定义一个二进制文件,只有字符串才能写入硬盘,所以字典要先转换为字符串. pickle.dump(acc

python学习道路(day5note)(列表生成式,生成器,装饰器,常用模块)

生成列表的方式 data = [1,2,3]  需求   每个数字加上1 # data = ( x*2 for x in range(5)) print(data) 列表生成式 后面的I赋予加1操作,i+q只能放在前面 加上三元运算可以 生成器 (惰性运算,算到哪个值就到哪个值,往后就不算了)就是一个推到行算法 中括号叫做列表生成式,小括号叫做生成器 从左到右执行  当我访问到后面的数时候,前面的就没了 这样也是可以取值的,从左到右 斐波拉契数列 ### ### 转为生成器 加了yield 叫做