函数、装饰器、模块
一、函数
1.递归调用
定义:一个函数自己调用自己就是递归调用
举例说明:
def test1(): num = int(input('please enter a number:')) if num%2==0:#判断输入的数字是不是偶数 return True #如果是偶数的话,程序就退出了,返回true print('不是偶数请重新输入!') return test1()#如果不是偶数的话继续调用自己,输入值 print(test1())#调用test ---递归也是循环
2.高阶函数
定义:如果一个函数的入参是一个函数的话,那这个函数就是高阶函数
高阶函数的例子:
def add(x,y,z): #参数z是要传入一个函数名 res =z(x)+z(y) return res print(add('98','100',int))
3.函数即变量,意思就是说,只是一个函数名的话,它就是一个普通变量,这个变量里面存的是这个函数里面的代码而已,函数只有在调用的时候才会执行
举例说明函数即变量:
def hello(name): print(name) new_hello = hello#定义一变量=hello,指向的是hello这个函数的函数体 hello('hello..') new_hello('new hello...') print(type(hello)) #查看hello的type print(type(new_hello))#查看new_hello的type
4.函数的作用域,就近原则,从里往外找,如果自己函数里有,就拿过来,如果自己的函数里面没有的话,就去它父级函数里找
例子:
def wrapper(): name= '大师兄,妖怪来了' def deco(): name ='哈哈' print('我在里面%s'%name) def hhh(): print('xxx%s'%name) hhh() deco() print('w外面是%s'%name) wrapper()#调用函数
5.装饰器
1.函数里面也可以嵌套的定义一个函数
2.高阶函数
装饰器说白了就是函数嵌套+高阶函数
装饰器的作用就是在不改变原有的函数的调用方式,入参的情况下,给函数添加新功能
#偷偷摸摸的给函数加上新功能
举例说明:
import time def timer(func): def deco(*args,**kwargs): start_time = time.time() # 开始时间 func() end_time = time.time() # 结束时间 print('run函数运行时间是:', end_time - start_time) return deco #此函数其实就是返回了一个函数名而已,函数只有调用才会执行 def run(): print('run..') time.sleep(1) run= timer(run) #函数调用 run==deco,此处改变了函数的调用方式 #1.调用timer函数的时候,要传入一个方法名, # timer函数在函数内部定义了一个函数叫做deco #又在函数deco内部调用了timer里面传入的方法,func()接收了原来的run方法 #run保存的是deco,deco是一个函数,调用run就是调用deco
run()#run()=deco() 上面的代码改进一下就引出了装饰器的用法 import time def timer(func): def deco(*args,**kwargs): start_time = time.time() # 开始时间 func() end_time = time.time() # 结束时间 print('run函数运行时间是:', end_time - start_time) return deco @timer #@timer相当于run=timer(run) def run(): print('run..') time.sleep(1) run()#因为上面的@timer,所以在函数调用的时候不必再写run=timer(run) 带参数的装饰器函数 import time def timer(func): def deco(*args,**kwargs): #*args,**kwargs 用来接收传函数的参数 start_time = time.time() func(*args,**kwargs)#获取返回值 end_time = time.time() print('run函数运行时间是:',end_time-start_time) return deco @timer def run2(name): print(name) print('run2..') time.sleep(0.5) run2('huanghf')
二、Python内置函数
print(all([1,2,3,4])) #判断可迭代的对象里面的值是否为真 print(any([0,1,2,3]))#判断可迭代的对象里面的值是否有一个为真 print(bin(10)) #十进制转二进制 print(bool('s')) #把一个对象转换成布尔类型
其它强制类型转换: int()#整型 float()#小数 str()#字符串 list()#列表 set()#集合 tuple()#元组
def func(): pass print(callable('func'))#判断传入的对象是否可调用 print(chr(98)) #打印数字对应的ascii print(ord('b')) #打印字符串对应的ascii print(dict(a=1,b=2)) #转换字典 print(dir(func))#打印传入对象的可调用方法 print(eval('[]')) #执行python代码,只能执行简单的,定义数据类型和运算 print(exec('def a():pass')) #执行python代码 def func(num): return num filter(func,[1,2,3,4])#根据前面的函数处理逻辑,依次处理后面可迭代对象里面的每个元素,返回True保存 print(filter(func,[1,2,3,4]))#Python2中这么用是没问题的 print(list(filter(func,[1,2,3,4]))) #Python3中得这么用才没问题 map(func, [1, 2, 3, 4]) #根据前面的函数处理逻辑,依次处理后面可迭代对象里面的每个元素,保存前面函数返回的所有结果 print(globals())#返回程序内所有的变量,返回的是一个字典 print(locals()) # 返回局部变量 print(hex(111)) # 数字转成16进制 print(max(111, 12)) # 取最大值 print(oct(111)) # 把数字转换成8进制 print(round(11.11, 2)) # 取几位小数 print(sorted([2, 31, 34, 6, 1, 23, 4])) # 排序 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') # 导入一个模块
三、模块
什么是模块,模块就是一个Python文件
1.模块的导入方法:
import module #导入模块
from module import * #导入该模块中的所有方法,慎用
from module import fun as xx_fun #导入指定的方法,然后起别名
from module import fun1,fun2,fun3 #导入模块下的多个方法
举例说明:
pycharm文件夹下有两个文件model与model2 model代码如下: def run(): print('这是在model里面的run函数') def run1(): print('run1...') def run2(): print('run2...') name = 5 模块调用: import model #import的本质就是把这个python文件从头到尾执行一次 model.run() >>>这是在model里面的run函数 from model import run,run1 #只导入某个函数的时候 run() run1() from model import * #这种最好不要用,从一个模块中导入所有的函数,如果导入几个模块,报错不知道是哪个文件中的函数出问题了 run() run1() from model import name #导入model中的变量,函数和变量都能导入 print(name) from day04.set1 import hhh #这个是在其他目录下的话 hhh() 包和文件夹的区别就是包下面有个__init__.py 在python2里面,如果你要导入其他文件夹下面的python文件,那么必须是一个包 python3不需要,只是文件夹就行了 以上导入模块Pycharm右键运行model2文件不会报错,但在Pycharm的Terminal下会报错,这是因为Pycharm右键运行会主动把变量加到环境变量,Terminal不会,所以就报错了 什么是环境变量?--环境变量就是可以让用户在任意一个目录都可以使用某个命令 导入模块的时候,python首先在当前目录下去找这个模块,如果当前目录下没有找到这个文件的话,就会去环境变量里面的目录找,如果没有找到就就报错 import sys print(sys.path) #查看系统变量 sys.path.append(r'D:\hhf\day04') #添加环境变量 from day04.set1 import hhh #此时在Terminal下不会报错
2random模块
import random #导入random模块 print(random.random()) #随机浮点数,默认取0-1,不能指定范围 print(random.randint(1,20)) #随机整数 1-19,顾头不顾尾 print(random.randrange(1,20)) #随机产生一个range print(random.choice('x223aet')) #随机取一个元素,变量为可迭代元素即可 print(random.sample('hello',2)) #从序列中随机取几个元素,返回的是一个list print(random.uniform(1,999)) #随机浮点数,可以指定范围 x=[1,2,3,4,56,7] random.shuffle(x) #洗牌,打乱顺序,会改变原list的值 print(x)
3.json模块(www.bejson.com校验json串是否合法的网站)
json是一种所有语言中都通用的key-value数据结构的数据类型,很像python中的字典,json处理使用json模块,json模块下常用的方法:
json和python中的字典类型很像,但是json里面只能用双引号,不能是单引号,json串实际上就是一个字符串,json可以用字典和list
import json #此段代码将json串或者字符串转换成字典 json_str=''' { "username":"hhf", "passwd":123456, "flag":true } ''' users文件中内容为 { "hhh": { "price": "90000", "password": "123456" }, "admin": { "password": "123456", "money": 8000 } } fr = open('users') #打开user文件 json_dic = json.loads(json_str)#json串(字符串)转成字典,loads方法是把json转成字典 json_dic_file = json.load(fr)#json串(字符串)转成字典,load方法是传入一个文件对象,然后load方法自动去读这个文件的内容,然后转成字典 print(json_dic) print(json_dic_file) print(type(json_dic),type(json_dic_file)) #下面的代码将字典转成json串 d = { "hhh": { "price": "90000", "password": "123456" }, "admin": { "password": "123456", "money": 8000 } } fw = open('user.json','a+') dic_str = json.dumps(d) #把字典变成json串(字符串) print(dic_str) print(type(dic_str)) json.dump(d,fw) #把字典变成json串(字符串),写入到文件 总结:
json可以用字典和list dump和dumps字典转json串的 load和loads是json串转字典 带s就和字符串沾边,不带s和文件对象沾边