1.包
1.1什么是包?
包是模块的的一种形式,包的本质就是一个含有 .py的文件夹。
1.2为什么要有包?
模块的第一个版本只有10个功能,但是未来在扩展版本的时候,模块名和用法应该最好不要去修改,但是这只是对使用者友好,而由于版本扩展,文件越来越大,模块设计者对模块的管理、维护会越来越复杂,因此我们可以使用包来扩展模块的功能。
1.3如何使用包
1.3.1 模块和包
导入模块发生的三件事: 创建一个包的名称空间 执行py文件,将执行过程中产生的名字存放于名称空间中。 在当前执行文件中拿到一个名字aaa,aaa是指向包的名称空间的 导入包发生的三件事: 创建一个包的名称空间 由于包是一个文件夹,无法执行包,因此执行包下的.py文件,将执行过程中产生的名字存放于包名称空间中(即包名称空间中存放的名字都是来自于.py) 在当前执行文件中拿到一个名字aaa,aaa是指向包的名称空间的 导入包就是在导入包下的.py,并且可以使用以下两种方式导入: import ... from ... import...
1.3.2扩展模块的功能
如下我们如果需要扩展aaa.py模块,需要建立一个aaa的目录文件,并且删除aaa.py文件,将aaa.py修改成m1.py和m2.py两个文件,让模块的功能使用方法不改变
# aaa.py def func1(): pass def func2(): pass def func3(): pass def func4(): pass
# m1.py def func1(): pass def func2(): pass
def func3(): pass def func4(): pass
# run.py import aaa aaa.func1() aaa.func2() aaa.func3() aaa.func4()
2.包是含有__init__.py的文件夹; 导包就是导入__init__#
3.包一定是被当作模块文件导入,模块文件 m1.py/m2.py 的搜索路径以执行文件 包的介绍.py 路径为准
1.4修改 __ init __.py文件
# aaa/.py func1 = 111 func2 = 222 func3 = 333 func4 = 444
由于在__init__.py
中定义了func1,因此我们可以在run.py文件中导入func1,但是这个func1并不是我们想要的func1,因此需要修改__init__.py
文件,又由于执行文件run.py的环境变量不为aaa,因此直接使用import导入m1会报错,因此使用from导入。
# aaa/.py from aaa.m1 import func1 from aaa.m2 import func2
# run.py import aaa print(aaa.func1()) print(aaa.func2())
1.5包的作用
包的作用:当模块内部函数过多,为了方便管理模块,把一个模块划分成多个模块,但是又不能改变导入方式,把多个# 模块放入一个包(文件夹)内。未来导包就是导init
2.time模块
time模块:提供了三种不同类型的时间(时间戳),三种不同类型的时间可以相互转换
import time
# 时间戳形式 print(time.time()) #1569651011.655515
# 格式化时间 print(time.strftime('%Y-%m-%d %X')) #2019-09-28 14:15:23
# 结构化时间的基准时间 print(time.localtime(0)) print(time.localtime()) #time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0) #time.struct_time(tm_year=2019, tm_mon=9, tm_mday=28, tm_hour=14, tm_min=18, tm_sec=57, tm_wday=5, tm_yday=271, tm_isdst=0)
time.time() time.sleep(1) # 相隔一秒打印
3.datetime模块
# datetime模块:时间的加减 import datetime now = datetime.datetime.now() print(now) 结果列:2019-09-28 14:28:01.221402 # 默认3天 print(now + datetime.timedelta(3)) 结果列:2019-10-01 14:28:01.221402 # 加3周 print(now + datetime.timedelta(weeks=3)) 结果列:2019-10-19 14:28:01.221402 # 加3小时 print(now + datetime.timedelta(hours=3)) # 减3小时 print(now - datetime.timedelta(hours=3)) print(now + datetime.timedelta(hours=-3)) print(now.replace(year=1949, month=10, day=1, hour=10, minute=1, second=0, microsecond=0)) 结果:1949-10-01 10:01:00
4.random模块
# random模块:随机数 import random #掌握 # 0- 1 print(random.random()) #[1-3] print(random.randint(1,3)) # 3 # 打乱 lt = [1,2,3] random.shuffle(lt) print(lt) #随机选择一个 print(random.choice(lt)) #只随机一次 --》 梅森旋转算法 import time # random.seed(time.time()) # random.seed(123) print(random.random()) #了解 print(random.sample([1,"a","c",2,3,4],2)) #['a', 4]
5.hashlib模块
5.1 hash是什么?
hash是一种算法,该算法接受传入内容,经过运算得到一串hash值。
5.2 hash值的特点
- 只要传入的内容一样,得到的hash值一样,可用于非明文密码传输时密码校验
- 不能由hash值返解成内容,即可以保证非明文密码的安全性
- 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的,可以用于对文本的哈希处理
hashlib模块:对字符加密
hmac模块:对字符加密,并且加上密钥
import hashlib
叠加性
import hashlib m = hashlib.md5() m.update(b'say') m.update(b'hello') m.update(b'adsfb') print(m.hexdigest())# 对于不同的字符而言,用不重复 #3c277b188b4dd5ac4981ffe9698c289d
手机号/生日/性别/qq账号/以前的密码/ --》 挖矿(算法)
hash_pwd = '0562b36c3c5a3925dbe3c4d32a4f2ba2' # # pwd_list = [ # 'hash3714', # 'hash1313', # 'hash94139413', # 'hash123456', # '123456hash', # 'h123ash', # ] # # for pwd in pwd_list: # m = hashlib.md5() # m.update(pwd.encode('utf8')) # res = m.hexdigest() # if res == hash_pwd: # print(f'获取密码成功:{pwd}') # 获取密码成功:hash123456
hmac 密钥
import hmac m = hmac.new(b'maerzi') m.update(b'hash123456') # f82317e44545b0ab087109454814b5c4 print(m.hexdigest()) m = hmac.new(b'sdfjhjk2394879ul%$$Y#($&') m.update(b'hash123456') # 2a70fd0f13cb49357f40d326a4e071a2 print(m.hexdigest()) pwd_list = [ 'hash3714', 'hash1313', 'hash94139413', 'hash123456', '123456hash', 'h123ash',
6.typing模块
typing模块:与函数联用,控制函数参数的数据类型,提供了基础数据类型之外的数据类型
lt = [1, 2, 3, 4] print(type(lt) is list) from typing import Iterable, Iterator, Generator def func(x: int, lt: Iterable) -> list: return [1, 2, 3] func(10, '123123')
7.requests模块:
requests模块:爬虫--》爬数据,模拟浏览器对url发送请求,拿到数据。
url ——> 一个特定的网址 -》 用不重复
import requests
import requests response = requests.get('https://ishuo.cn') data = response.text print(data) import re
正则re:从大的字符串中挑选出 具有某种形状特点的字符串
爬虫列题: import requests response = requests.get('https://ishuo.cn') data = response.text print(data) import re import re # .*?表示所有类型的都要 content_list = [] content_res = re.findall('<div class="content">(.*?)</div>', data) for i in content_res: # type:str if i.startswith('<ul>'): continue content_list.append(i) # print(content_list) title_list = re.findall('</span><a href="/subject/.*?">(.*?)</a>', data) # print(title_list) # title_content_dict = {} # for i in range(len(content_list)): # title_content_dict[title_list[i]] = content_list[i] title_content_dict = {k: v for k, v in zip(title_list, content_list)} with open('duanzi.txt', 'w', encoding='utf8') as fw: for k, v in title_content_dict.items(): fw.write(f'{k}:\n{v}\n\n')
8.re模块
re模块: 去字符串找 符合某种特点的字符串
import re
# re模块: 去字符串找 符合某种特点的字符串 import re # s = '去字符串找符合某种特点的字符串' # # res = re.findall('', s) # print(res) # 元字符 s = 'abcdabc' # abc # abc # bc bc # ^:以...开头 res = re.findall('^ab', s) print(res) res = re.findall('^bc', s) print(res) # $: 以..结尾 s = 'abcdabc' res = re.findall('bc$', s) print(res) # .: 任意字符 s = 'abc红abc' res = re.findall('abc.', s) print(res) # \d: 数字 s = 'skld2342ljk' res = re.findall('\d', s) print(res) # \w: 非空,数字字母下划线 s = 'skld_23 42ljk' res = re.findall('\w', s) print(res) # \s:空,空格/\t/\n s = 'skld_23 42ljk' res = re.findall('\s', s) print(res) # \D: 非数字 s = 'skld2342ljk' res = re.findall('\D', s) print(res) # \W: 空 s = 'skld_23 42ljk' res = re.findall('\W', s) print(res) # \S:非空 s = 'skld_23 42ljk' res = re.findall('\S', s) print(res) # +: 前面的一个字符至少1个 s = 'abcddddd abcd abc' print(re.findall('abcd+', s)) # ?:前面的一个字符0-1个 s = 'abcddddd abcd abc' print(re.findall('abcd?', s)) # *:前面的一个字符至少0个 s = 'abcdddddddddddddddddd abcd abc' print(re.findall('abcd*', s)) # []: 中括号内的都可以 s = 'abc bbc cbc dbc' print(re.findall('[abc]bc', s)) # [^]: 中括号的都不可以 s = 'abc bbc cbc dbc' print(re.findall('[^abc]bc', s)) # |:或 s = 'abc bbc dbc' print(re.findall('abc|bbc', s)) # {2}:前面的字符2个 s = 'abccabc abccc' print(re.findall('abc{2}', s)) # {1,2}:前面的字符2个 s = 'abccabc abccc' print(re.findall('abc{1,2}', s)) # 贪婪模式 # .(任意字符)*(0-无穷个) s = 'abcdefgbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbg' print(re.findall('a.*g', s)) # 非贪婪模式(*******) # .(任意字符)*(0-无穷个)?(让他进入非贪婪模式) s = 'abcdefgbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbg' print(re.findall('a.*?g', s)) # bug # .(任意字符)*(0-无穷个)?(让他进入非贪婪模式) s = 'abcdefg' print(re.findall('.*?', s)) # 了解:特殊构造 # a(?=\d) :a后面是数字,但是不要数字,不消耗字符串内容 s = 'a123 aaaa a234 abc' # a1 aa # aa # aa a2 ab print(re.findall('a(?=\d)', s)) print(re.findall('a(?=\w)', s)) # 匹配邮箱: s = '#@#@#@nickchen121@163.com$$$$////nick@qq.com$$#$#$[]]2287273393@162.com@$2423423lksdlfj#' # \w(字母/数字/下划线)+(0-无穷个)@ \w(字母/数字/下划线)+(0-无穷个).com print(re.findall('\w+@\w+.com', s)) # 函数 ## compile s = 'abcd abcddd abc' # res = re.compile('abcd*') email_pattern = re.compile('\w+@\w+.com') phone_patter = re.compile('\d{13}') print(re.findall(email_pattern, s)) print(re.findall('abcd*', s)) # ## match: 从开头找一个,找得到就不找了 ;找不到报错 --》 # s = 'ab abcddd abc' # res = re.match('abcd*', s) # print(res.group()) ## search: 从字符串找一个,就不找了 s = 'ab abcddd abc' res = re.search('abcd*', s) print(res.group()) ## split s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj' print(re.split('\d+', s)) ## sub == replace s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj' print(re.sub('\d+', ' ', s)) ## subn --> 替换了多少次 s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj' print(re.subn('\d+', ' ', s)) # 补充(非常有用) ## 修饰符 --> re.S会让.匹配换行符(*****) s = '''abc abcabc*abc ''' # .不匹配换行 print(re.findall('abc.abc', s)) # ['abc*abc'] print(re.findall('abc.abc', s, re.S)) # ['abc\nabc', 'abc*abc'] ## 分组 --> 只要括号里的(*****) s = 'abc abcd abcdd' print(re.findall('a(.)c(d)', s)) ## 有名分组(了解) s = 'abc abcd abcdd' print(re.search('a(?P<name>.)c(?P<name2>d)', s).groupdict()) # 超高级用法 s = 'abc123abc123' # c123a print(re.sub('c(\d+)a', ' ', s)) print(re.sub('c(?P<name1>\d+)a', ' \g<name1> ', s)) # \g<name1>这个东西不能替换掉 # 以下必须得记住 # .*? # 贪婪和非贪婪 # findall # re.S # match和sarch的区别 # 分组 # 有名分组:给分组加名字 # 哪些做了解 # 杂七杂八的元字符 # 特殊构造元字符 # 特殊修饰符