Python基础之匿名函数、包、模块及常见模块介绍
一、匿名函数
一般与内置函数一起使用
定义的规范: 函数名 = lambda 参数 :返回值
例子:
#如下面这段代码 def calc(n): return n**n print(calc(5)) #换成匿名函数 calc = lambda n:n**n print(calc(5))
Python中:常用的一些内置函数:
map(映射) zip(拉链) filter(过滤) sorted(排序) reduce(叠加) 大部分都是基于for循环
map的应用:
l=['alex','lxx','wxx','薛妻'] new_l=(name+'_dsb' for name in l) print(new_l) #用匿名函数 # res=map(lambda name:name+'_dsb',l) #map相当于for循环 # print(res) # 生成器
filter的应用:
# l=['alex_sb','lxx_sb','wxx','薛妻'] # res=(name for name in l if name.endswith('sb')) # print(res) # res=filter(lambda name:name.endswith('sb'),l) # print(res)
综合举例子:
salaries={ 'siry':3000, 'tom':7000, 'lili':10000, 'jack':2000 } # 迭代出的内容 比较的值 # 'siry' 3000 # 'tom' 7000 # 'lili' 10000 # 'jack' 2000 # def func(k): # return salaries[k] # max的应用 # res=max(salaries,key=func) # 返回值=func('siry') # print(res) # res=max(salaries,key=lambda k:salaries[k]) # print(res) # min的应用 # res=min(salaries,key=lambda k:salaries[k]) # print(res) #sorted排序 # salaries={ # 'siry':3000, # 'tom':7000, # 'lili':10000, # 'jack':2000 # } res=sorted(salaries,key=lambda k:salaries[k],reverse=True) # print(res)
二、模块
1.模块就是一系列功能的集合体,分为三大类
I:内置的模块
II:第三方的模块
III:自定义的模块。
一个python文件本身就一个模块,文件名m.py,模块名叫m2.模块有四种形式
1 使用python编写的.py文件
2 已被编译为共享库或DLL的C或C++扩展
3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)
4 使用C编写并链接到python解释器的内置模块y=333 z=444 import foo #首次导入模块会发生3件事 # 1、执行foo.py # 2、产生foo.py的名称空间,将foo.py运行过程中产生的名字都丢到foo的名称空间中 # 3、在当前文件中产生的有一个名字foo,该名字指向2中产生的名称空间 # 之后的导入,都是直接引用首次导入产生的foo.py名称空间,不会重复执行代码 # import foo # import foo
引用
# 引用: # print(foo.x) # print(foo.get) # print(foo.change) # 1:模块名.名字,是指名道姓地问某一个模块要名字对应的值,不会与当前名称空间中的名字发生冲突 # x=1111111111111 # print(x) # print(foo.x) # 2:无论是查看还是修改操作的都是模块本身,与调用位置无关 # import foo # x=3333333333 # # foo.get() # # foo.change() # print(x) # print(foo.x) # foo.get()
导入(导入规范:先导入内置的,再导入第三方的,最后导入自定义的)
#可以以逗号为分隔符在一行导入多个模块 import time,foo,m #不推荐 #推荐 # import time # import foo # import m
可以给模块取别名
语法:import 模块 as 别名
# import foo as f # 相当于f=foo # f.get() #直接使用
4.模块导入之:from ... import ...
此种导入也发生了三件事
产一个模块的名称空间
运行foo.py将运行过程中产生的名字都丢到模块的名称空间去
在当前名称空间拿到一个名字,该名字与模块名称空间中的某一个内存地址
例子:
from spam import read1,read2 # 在spam模块中导入 read1 和read2 所指的内存空间地址 from spam import * #代表导入包全部,不推荐,消耗太多资源
5.模块查找路径
优先级:
1、内存(内置模块)
2、硬盘:按照sys.path中存放的文件的顺序依次查找要导入的模块
from dir.dir1 import m m.f1() """ 绝对导入必须依据执行文件所在的文件夹路径为准 1.绝对导入无论在执行文件中还是被导入文件都适用 相对导入 .代表的当前路径 ..代表的上一级路径 ...代表的是上上一级路径 注意相对导入不能在执行文件中使用 相对导入只能在被导入的模块中使用,使用相对导入就不需要考虑 执行文件到底是谁 只需要知道模块与模块之间路径关系 """
三、包
1.包就是一个包含有__init__.py文件的文件夹。包的本质是模块的模块的一种形式,包是用来被当做模块导入
2.包导入也执行了三件事
1、产生一个名称空间
2、运行包下的__init__.py文件,将运行过程中产生的名字都丢到1的名称空间中
3、在当前执行文件的名称空间中拿到一个名字包名,包名指向1的名称空间
3.导入方式与模块类似,导入方法也类似
四、各类模块
1.时间模块(time)
import time # 时间分为三种格式: # 1、时间戳:从1970年到现在经过的秒数 # 作用:用于时间间隔的计算 # print(time.time()) # 2、按照某种格式显示的时间:2020-03-30 11:11:11 # 作用:用于展示时间 # print(time.strftime('%Y-%m-%d %H:%M:%S %p')) # print(time.strftime('%Y-%m-%d %X')) # 3、结构化的时间 # 作用:用于单独获取时间的某一部分 # res=time.localtime() # print(res) # print(res.tm_year) #当地时间的年 # print(res.tm_yday) #二:datetime import datetime # print(datetime.datetime.now()) # print(datetime.datetime.now() + datetime.timedelta(days=3)) # print(datetime.datetime.now() + datetime.timedelta(weeks=1)) # 时间模块需要掌握的操作 # 1、时间格式的转换 # struct_time转为时间戳 import time # s_time=time.localtime() # print(time.mktime(s_time)) # 时间戳转化为struct_time # tp_time=time.time() # print(time.localtime(tp_time)) # 补充:世界标准时间与本地时间 # print(time.localtime()) # print(time.gmtime()) # 世界标准时间,了解 # print(time.localtime(333)) # print(time.gmtime(333)) # struct_time转化为格式化的字符串形式的时间 # s_time=time.localtime() # print(time.strftime('%Y-%m-%d %H:%M:%S',s_time)) # print(time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S')) # 真正需要掌握:format string<------>timestamp # '1988-03-03 11:11:11'+7 # format string--->struct_time--->timestamp # struct_time=time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S') # timestamp=time.mktime(struct_time)+7*86400 # print(timestamp) # format string<---struct_time<---timestamp # res=time.strftime('%Y-%m-%d %X',time.localtime(timestamp)) # print(res) # time.sleep(3) # 了解 # import time # print(time.asctime()) import datetime # print(datetime.datetime.now()) # print(datetime.datetime.utcnow()) print(datetime.datetime.fromtimestamp(333333))
2.随机模块random
import random # print(random.random()) #(0,1)----float 大于0且小于1之间的小数 # print(random.randint(1, 3)) # [1,3] 大于等于1且小于等于3之间的整数 # print(random.randrange(1, 3)) # [1,3) 大于等于1且小于3之间的整数 # # print(random.choice([111, 'aaa', [4, 5]])) # 111或者'aaa'或者[4,5] # # print(random.sample([111, 'aaa', 'ccc','ddd'],2)) # 列表元素任意2个组合 # # print(random.uniform(1, 3)) # 大于1小于3的小数,如1.927109612082716 # # item = [1, 3, 5, 7, 9] # random.shuffle(item) # 打乱item的顺序,相当于"洗牌" # print(item) # 应用:随机验证码 # import random # # res='' # for i in range(6): # 从26大写字母中随机取出一个=chr(random.randint(65,90)) # 从10个数字中随机取出一个=str(random.randint(0,9)) # # 随机字符=random.choice([从26大写字母中随机取出一个,从10个数字中随机取出一个]) # res+=随机字符 import random def make_code(size=4): res='' for i in range(size): s1=chr(random.randint(65,90)) s2=str(random.randint(0,9)) res+=random.choice([s1,s2]) return res print(make_code(6))
3.操作路径文件:os模块
import os # 获取某一个文件夹下所有的子文件以及子文件夹的名字 # res=os.listdir('.') # print(res) size=os.path.getsize(r'/Users/linhaifeng/PycharmProjects/s14/day22/01 时间模块.py') # print(size) # os.remove() 删除一个文件 # os.rename("oldname","newname") 重命名文件/目录 # 规定:key与value必须都为字符串 # os.environ['aaaaaaaaaa']='111' # print(os.environ) # print(os.path.dirname(r'/a/b/c/d.txt')) # print(os.path.basename(r'/a/b/c/d.txt')) # print(os.path.isfile(r'笔记.txt')) # print(os.path.isfile(r'aaa')) # print(os.path.isdir(r'aaa')) # print(os.path.join('a','/','b','c','d')) # 推荐用这种 BASE_DIR=os.path.dirname(os.path.dirname(__file__)) # print(BASE_DIR) # BASE_DIR=os.path.normpath(os.path.join( # __file__, # '..', # '..' # )) # print(BASE_DIR) # 在python3.5之后,推出了一个新的模块pathlib from pathlib import Path # res = Path(__file__).parent.parent # print(res) # res=Path('/a/b/c') / 'd/e.txt' # print(res) # print(res.resolve())
4.序列化与反序列化模块:json和pickle
json 是可互操作的,在 Python 系统之外广泛使用,而 pickle 则是 Python 专用的; 默认情况下,json 只能表示 Python 内置类型的子集,不能表示自定义的类; 但 pickle 可以表示大量的 Python 数据类型。
# import json # # 序列化 # json_res=json.dumps([1,'aaa',True,False]) # # print(json_res,type(json_res)) # "[1, "aaa", true, false]" # # # 反序列化 # l=json.loads(json_res) # print(l,type(l)) # 示范2: import json # 序列化的结果写入文件的复杂方法 # json_res=json.dumps([1,'aaa',True,False]) # # print(json_res,type(json_res)) # "[1, "aaa", true, false]" # with open('test.json',mode='wt',encoding='utf-8') as f: # f.write(json_res) # 将序列化的结果写入文件的简单方法 # with open('test.json',mode='wt',encoding='utf-8') as f: # json.dump([1,'aaa',True,False],f) # 从文件读取json格式的字符串进行反序列化操作的复杂方法 # with open('test.json',mode='rt',encoding='utf-8') as f: # json_res=f.read() # l=json.loads(json_res) # print(l,type(l)) # 从文件读取json格式的字符串进行反序列化操作的简单方法 # with open('test.json',mode='rt',encoding='utf-8') as f: # l=json.load(f) # print(l,type(l)) # json验证: json格式兼容的是所有语言通用的数据类型,不能识别某一语言的所独有的类型 # json.dumps({1,2,3,4,5}) # json强调:一定要搞清楚json格式,不要与python混淆 # l=json.loads('[1, "aaa", true, false]') # l=json.loads("[1,1.3,true,'aaa', true, false]") # print(l[0]) # 了解 # l = json.loads(b'[1, "aaa", true, false]') # print(l, type(l)) # with open('test.json',mode='rb') as f: # l=json.load(f) # res=json.dumps({'name':'哈哈哈'}) # print(res,type(res)) # res=json.loads('{"name": "\u54c8\u54c8\u54c8"}') # print(res,type(res)) # 4、猴子补丁 # 在入口处打猴子补丁 # import json # import ujson # # def monkey_patch_json(): # json.__name__ = 'ujson' # json.dumps = ujson.dumps # json.loads = ujson.loads # # monkey_patch_json() # 在入口文件出运行 # import ujson as json #这是 不行 # 后续代码中的应用 # json.dumps() # json.dumps() # json.dumps() # json.loads() # json.loads() # json.loads() # 5.pickle模块 import pickle # res=pickle.dumps({1,2,3,4,5}) # print(res,type(res)) # s=pickle.loads(res) # print(s,type(s))
5.ConfigParser模块
configparser模块主要用于读取配置文件。配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。
import configparser config=configparser.ConfigParser() config.read('test.ini') #获取配置文件test的配置信息 # 1、获取sections,以列表形式返回configparser对象的所有节点信息 # 获取所有节点 all_sections = config.sections() print('sections: ', all_sections) # 结果sections: ['user', 'connect'] # 2、获取某一section下的所有options 以列表形式返回某个节点section的所有key值 # 获取指定节点的options信息 options = config.options('user') print(options) # 结果 ['user_name', 'password'] # 3、获取items # 获取user节点的配置信息 items = config.items('user') print(items) # 结果 [('user_name', "'Mr,X'"), ('password', "'222'")] # 4、获取指定节点下指定option的值 # res=config.get('section1','user') # print(res,type(res)) 返回结果是字符串类型 # res=config.getint('section1','age') # print(res,type(res)) 返回结果是int类型 # res=config.getboolean('section1','is_admin') # print(res,type(res)) 返回结果是bool类型 # res=config.getfloat('section1','salary') # print(res,type(res)) 返回结果是float类型
6.hash模块
hash一类算法,该算法接受传入的内容,经过运算得到一串hash值。不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定。用于密码密文传输与验证。于文件完整性校验
# import hashlib # # m=hashlib.md5() # m.update('hello'.encode('utf-8')) # m.update('world'.encode('utf-8')) # res=m.hexdigest() # 'helloworld' # print(res) # # m1=hashlib.md5('he'.encode('utf-8')) # m1.update('llo'.encode('utf-8')) # m1.update('w'.encode('utf-8')) # m1.update('orld'.encode('utf-8')) # res=m1.hexdigest()# 'helloworld' # print(res) # 模拟撞库 # cryptograph='aee949757a2e698417463d47acac93df' # import hashlib # # # 制作密码字段 # passwds=[ # 'aaa3714', # 'aaa313', # 'aaa94139413', # 'aaa123456', # '123456aaa', # 'a123aa', # ] # # dic={} # for p in passwds: # res=hashlib.md5(p.encode('utf-8')) # dic[p]=res.hexdigest() # # # 模拟撞库得到密码 # for k,v in dic.items(): # if v == cryptograph: # print('撞库成功,明文密码是:%s' %k) # break # 提升撞库的成本=>密码加盐 import hashlib m=hashlib.md5() m.update('地火'.encode('utf-8')) m.update('aaa3714'.encode('utf-8')) m.update('地虎'.encode('utf-8')) print(m.hexdigest())
7.subprocess模块
允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码。
import subprocess obj=subprocess.Popen('echo 123 ; ls / ; ls /root',shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) # print(obj) # res=obj.stdout.read() # print(res.decode('utf-8')) err_res=obj.stderr.read() print(err_res.decode('utf-8'))
8.日志模块logging
import logging logging.basicConfig( # 1、日志输出位置:1、终端 2、文件 filename='access.log', # 不指定,默认打印到终端 # 2、日志格式 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', # 3、时间格式 datefmt='%Y-%m-%d %H:%M:%S %p', # 4、日志级别 # critical => 50 # error => 40 # warning => 30 # info => 20 # debug => 10 level=10, ) logging.debug('调试debug') # 10 logging.info('消息info') # 20 logging.warning('警告warn')# 30 logging.error('提现失败') # 40 logging.critical('严重critical') # 50
9.re正则模块
import re # print(re.findall('\w','aAbc123_*()-=')) # print(re.findall('\W','aAbc123_*()-= ')) # print(re.findall('\s','aA\rbc\t\n12\f3_*()-= ')) # print(re.findall('\S','aA\rbc\t\n12\f3_*()-= ')) # print(re.findall('\d','aA\rbc\t\n12\f3_*()-= ')) # print(re.findall('\D','aA\rbc\t\n12\f3_*()-= ')) # print(re.findall('\D','aA\rbc\t\n12\f3_*()-= ')) # print(re.findall('^aaa','aaais aaa sb')) # print(re.findall('sb$','aaais aaa sb')) # print(re.findall('sb$',"""aaa # aaais # aaa # sb # """)) # print(re.findall('^aaa$','aaais aaa sb')) # print(re.findall('^aaa$','al aa')) # print(re.findall('^aaa$','aaa')) # 重复匹配:| . | * | ? | .* | .*? | + | {n,m} | # 1、.:匹配除了\n之外任意一个字符,指定re.DOTALL之后才能匹配换行符 # print(re.findall('a.b','a1b a2b a b abbbb a\nb a\tb a*b')) # a.b # ['a1b','a2b','a b','abb','a\tb','a*b'] # print(re.findall('a.b','a1b a2b a b abbbb a\nb a\tb a*b',re.DOTALL)) # 2、*:左侧字符重复0次或无穷次,性格贪婪 # print(re.findall('ab*','a ab abb abbbbbbbb bbbbbbbb')) # ab* #['a','ab','abb','abbbbbbbb'] # 3、+:左侧字符重复1次或无穷次,性格贪婪 # print(re.findall('ab+','a ab abb abbbbbbbb bbbbbbbb')) # ab+ # 4、?:左侧字符重复0次或1次,性格贪婪 # print(re.findall('ab?','a ab abb abbbbbbbb bbbbbbbb')) # ab? # ['a','ab','ab','ab'] # 5、{n,m}:左侧字符重复n次到m次,性格贪婪 # {0,} => * # {1,} => + # {0,1} => ? # {n}单独一个n代表只出现n次,多一次不行少一次也不行 # print(re.findall('ab{2,5}','a ab abb abbb abbbb abbbbbbbb bbbbbbbb')) # ab{2,5} # ['abb','abbb','abbbb','abbbbb] # print(re.findall('\d+\.?\d*',"asdfasdf123as1111111.123dfa12adsf1asdf3")) # \d+\.?\d* \d+\.?\d+ # []匹配指定字符中的一个 # print(re.findall('a\db','a1111111b a3b a4b a9b aXb a b a\nb',re.DOTALL)) # print(re.findall('a[501234]b','a1111111b a3b a4b a9b aXb a b a\nb',re.DOTALL)) # print(re.findall('a[0-5]b','a1111111b a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL)) # print(re.findall('a[0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL)) # # print(re.findall('a[^0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL)) # print(re.findall('a-b','a-b aXb a b a\nb',re.DOTALL)) print(re.findall('a[-0-9\n]b','a-b a0b a1b a8b aXb a b a\nb',re.DOTALL))