目录
包
当项目越来越大,模块文件里功能越来越多,这时候把功能全部写在一个模块里就不是很好维护了,于是就有了包的概念,将功能分不同的文件和放在不同的包中,每个包里面存在一个__init__
文件,用于导入本层包内所有模块
包是模块一的一种形式,本质上就是一个含有.py的文件夹
导入包 发生了三件事情
- 创建一个包的名称空间
- 指向包下面的py文件,将执行产生的名字放于包名称空间中,即包名称空间中存放的名字都是来自于py文件中
- 在当前执行文件中拿到一个包名 指向包的名称空间
# 导入包就相当于导入包内的__init__文件,执行的时候以执行文件路径为搜索路径
# 对于用户来说 导入包不能改变调用方式
import aaa
aaa.m2()
aaa.m3()
导入包内包
导入包内包的话 要在第一层包__init__
文件里面导入第二层包的模块和方法,这样最外面执行文件可以不用改变调用方式
相对导入和绝对导入
# 绝对导入
from aaa.m1 import m1
from aaa.m2 import m2
from aaa.bbb import m3
from aaa.bbb import m4
# 相对导入
from .m1 import m1
from .m2 import m2
from .bbb import m3
from .bbb import m4
# 相对导入
# 导入包内包的话 也要在第一层包__init__文件里面导入第二层包的方法,这样,最外面执行文件可以不用改变调用方式导入
from ..bbb.m3 import m3
from ..bbb.m4 import m4
注意事项
- 包内的所有文件都是被导入使用,而不是被直接运行的。
- 包内部模块之间的导入可以使用绝对导入与相对导入,使用相对导入更好一点。
- 只有在文件被当做模块导入时才能使用相对导入的方法
- 凡是在导入时是相对导入时,
.
的左边必须是一个包
time模块
time模块 主要提欧共了三种不同类型的时间,三种不同类型可以相互转换
方法 | 描述 |
---|---|
time.time() | 时间戳形式 |
time.strftime('%Y-%m-%d %X') 最常用 | 格式化为 2019-09-27 22:53:19 |
time.localtime() | 结构化时间 |
import time
# 时间戳形式
print(time.time())
# 格式化时间
print(time.strftime('%Y-%m-%d %X'))
# 结构化时间
print(time.localtime())
# 结构化时间 --》 格式化时间
struct_time = time.localtime(3600*24*365)
print(time.strftime('%Y-%m-%d %X',struct_time))
# 格式化时间 --》 结构化时间
format_time = time.strftime('%Y-%m-%d %X')
print(time.strptime(format_time,'%Y-%m-%d %X'))
# 结构化时间 --》 时间戳
struct_time = time.localtime(3600*24*365)
print(time.mktime(struct_time))
# 时间戳 --》 结构化时间
time_stamp = time.time()
print(time.localtime(time_stamp))
datetime模块
datetime模块:时间上可以加减
import datetime
now = datetime.datetime.now()
print(now)
# 2019-09-28 19:53:31.924508
# 默认3天
print(now + datetime.timedelta(3))
# 加3周
print(now + datetime.timedelta(weeks=3))
# 加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
random模块
random 主要用于生成随机数
方法 | 描述 |
---|---|
random.random() | 生成 0-1 的随机数 |
random.randint(1,10) | 生成指定序列的随机数 |
random.randrange(1,3) | 生成指定序列的随机数 |
random.shuffle([1,2,45,6,8]) | 随机打乱顺序 |
import random
# 打印 0-1 的随机数,并不是真正的随机
print(random.random())
# 0.6629366744271181
# 打印随机数(1-10)
print(random.randint(1,10))
# 6
# 大于等于1且小于3的整数
print(random.randrange(1,3))
# 1
# 大于1小于3的小数
print(random.uniform(1,3))
# 2.0132434909012336
# 随机,打乱顺序
lis = [1,4,5,7,]
random.shuffle(lis)
print(lis)
print(random.choice(lis))
# 4
argparse 模块
argparse
这个模块可以帮助我们解析一些命令行传过来的参数并做一些处理
就像这样
python run.py --agt 6 --usr 1 --max_turn 40 --episodes 150 --movie_kb_path .\deep_dialog\data\movie_kb.1k.p --run_mode 2
def add_parser(parser):
# 添加一些可选参数
parser.add_argument("-dog", dest="dog", default="输入一只狗的名字", type=str, help="输入一只狗的名字/命令")
parser.add_argument("-u", "--ssh_user", dest="ssh_user", required=False, help="shh的用户名, 比如: root")
parser.add_argument("-tn", "--thread_num", dest="thread_num", required=False, help="并发线程数, 比如: 10")
def init_base():
# 声明一个参数解析对象
parser = argparse.ArgumentParser(prog="bible", description="统一自动化工具")
subparser = parser.add_subparsers(title="统一自动化工具", description="可用功能", help="功能具体使用", dest="action")
# 功能模板
template_parser = subparser.add_parser("template",help="功能")
add_parser(template_parser)
# #解析参数
args = parser.parse_args()
init_base()
--dog - 代表一个可选参数 也可以写成一个- -dog
dest - 保存到ArgumentParser对象时的 参数名,
default - 默认值,如果不输入参数默认显示到终端的名字
type - 将输入的字符串转化成改数据类型
help - 输入--help 时获得的帮助
required - 该命令行选项是否可以省略(只针对可选参数)。
action - 在命令行遇到该参数时采取的基本动作类型。
[root@localhost]# python test.py -h
usage: bible [-h] {template} ...
统一自动化工具
optional arguments:
-h, --help show this help message and exit
统一自动化工具:
可用功能
{template} 功能具体使用
template 功能
[root@localhost]# python test.py template -h
usage: bible template [-h] [-dog DOG] [-u SSH_USER] [-tn THREAD_NUM]
optional arguments:
-h, --help show this help message and exit
-dog DOG 输入一只狗的名字/命令
-u SSH_USER, --ssh_user SSH_USER
shh的用户名, 比如: root
-tn THREAD_NUM, --thread_num THREAD_NUM
并发线程数, 比如: 10
hashlib模块和hmac模块
hashlib 模块主要对字符串加密
hmac 模块不仅对字符加密,还加上了密钥,更加安全
import hashlib
import hmac
# hashlib
m = hashlib.md5()
m.update(b"qinyj123")
res = m.hexdigest()
print(res)
# a18973e94364927b08e7509dd3dbfde2 对于不同的字符而言,用不重复的密码
# hmac
m = hmac.new(b"qin1yj123123") # 加了一层密码
m.update(b"qinyj123")
res = m.hexdigest()
print(res)
# df1a1fcfaa4ec033406fe608b08ba45a
typing模块
typing 函数主要与函数一起连用,控制函数参数的数据类型用的,提供了基础数据类型之外的数据类型
lt = [1,2,3,4]
print(type(lt) is list)
# True
from typing import Iterable,Generator
def func(x:int, lt:Iterable) -> list:
return lt
res = func(10,lt)
print(res)
# [1, 2, 3, 4]
re模块
正则表达式,去字符串找符合某种特点的字符串
元字符 | 描述 |
---|---|
^ | 匹配规则:以什么什么开头 |
$ | 匹配规则:以什么什么结尾 |
. | 匹配任意字符 |
\d | 匹配 数字的 |
\D | 匹配 非数字的 |
\w | 匹配 非空 |
\W | 匹配 空的 |
\s | 匹配 空 |
\S | 匹配 非空 |
+ | 匹配 + 号前面的一个字符至少匹配0个 |
? | 匹配 ? 号前面的一个字符至少匹配0-1个 |
* | 匹配 * 号前面的一个字符至少匹配0个 |
[] | 匹配 [] 内的字符 |
[^] | [^] 内的字符都不匹配 |
| | 匹配 规则xx 或 规则xx |
{13} | 匹配 前面字符13个,比如手机号 |
{1,2} | 匹配 前面字符2个 |
贪婪模式 | 非贪婪模式 |
---|---|
.* 一直匹配,直到匹配完毕 | .*?进入非贪婪模式,匹配特定的 |
最常用的就是以下修饰符了
修饰符 | 描述 |
---|---|
re.l | 让匹配部分大小写 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
import re
# bug,应该都会打印出来
# s = "dhjsfsnfsnk"
# res = re.findall("",s)
# print(res)
# 以下全部是元字符
# 1. ^ 以什么什么开头
s = "sndkjbsfkbs"
print(re.findall("^sn",s))
# ['sn']
print(re.findall("^fkb",s))
# []
# 2. $ 以什么什么结尾
s = "sndkjbsfkbs"
print(re.findall("bs$",s))
# ['bs']
print(re.findall("dmskdhs$",s))
# []
# 3. . 匹配任意字符
s = "abc红abc"
print(re.findall(".",s))
# ['a', 'b', 'c', '红', 'a', 'b', 'c']
print(re.findall(".add",s))
# []
# 4. \d 匹配数字
s = "sndkjbsfkbs13275242sadbhajsv"
print(re.findall("\d",s))
# ['1', '3', '2', '7', '5', '2', '4', '2']
# 5. \w 匹配非空即不打印空,包括数字字母下划线
s = "abc"
print(re.findall("\w",s))
# ['a', 'b', 'c']
s = "a b c,dsds"
print(re.findall("\w",s))
# ['a', 'b', 'c']
# 6.\s 匹配空
s = "abc"
print(re.findall("\s",s))
s = "a b c,dsds"
print(re.findall("\s",s))
# [' ', ' ']
# 7. \D 匹配非数字
s = "abc123"
print(re.findall("\D",s))
# ['a', 'b', 'c']
# 8. \W 匹配空的
s = "a b c"
print(re.findall("\W",s))
# [' ', ' ']
# 9. \S 匹配非空的
s = "a b c"
print(re.findall("\S",s))
# ['a', 'b', 'c']
# 10. + 匹配 + 号前面的那一个字符 加上其他字符至少有一个就打印
s = "12345"
print(re.findall("23+",s))
# ['23']
# 11. ? 前面的一个字符0-1 个即可
s = "dafxsehtrnt"
print(re.findall("dat?",s))
# ['f', 'fl']
# 12. * 前面的一个字符至少0个
s = "dafxsehtrnt"
print(re.findall("@*",s))
# ['', '', '', '', '', '', '', '', '', '', '', '']
# 13. [] 只匹配中括号内的
s = "dmksff"
print(re.findall("[dmks]",s))
# ['d', 'm', 'k', 's']
# 14. [^] 中括号内的不匹配
s = "dfa"
print(re.findall("[^a]",s))
# ['d', 'f']
# 15. | 或
s = "dsajbfasfbia"
print(re.findall("dsa|bia",s))
# ['dsa', 'bia']
# 16. {2} 匹配前面的2个字符
s = "fsdsfs"
print(re.findall("fs{1,2}",s))
# ['fs', 'fs']
# 贪婪模式
# .*
s = "saaasaaas" # 找到最后
print(re.findall("s.*s",s))
# ['saaasaaas']
# 非贪婪模式 .*?
s = "saaasaaas" # 找到第一个不找了
print(re.findall("s.*?s",s))
# ['saaas']
# 匹配邮箱
# s = '#@#@#@nickchen121@163.com$$$$////nick@qq.com$$#$#$[]]2287273393@162.com@$2423423lksdlfj#'
s = "{|}{}|PP~#&(*$(^1342542daj@162.com/,/<>>]]}{}nicsh_snn@qq.comdsff1232//1213#$%^^asnjkgsa123@gmail.comdwanua"
print(re.findall("\w+@\w+.com",s))
# ['1342542daj@162.com', 'nicsh_snn@qq.com', 'asnjkgsa123@gmail.com']
# compile
s = '3728427482097jkcbdscvdb}:{}:{'
email_pattern = re.compile("\w+@\w+.com")
phone_pattern = re.compile("\d{13}")
print(re.findall(phone_pattern,s))
# ['3728427482097']
# match 从开头找一个,找到不找了报错
# s = 'ab abcddd abc'
# res = re.match('ab*', 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))
# ['ab', 'abcddd', 'abcasdfjlasjdk', 'l', 'lk', 'j', 'kl', 'kl', 'k', 'j', 'kl', 'j', 'lkj']
# sub == replace
s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj'
print(re.sub("\d+","",s))
# ababcdddabcasdfjlasjdkllkjklklkjkljlkj
# subn 替换了多少次
s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj'
print(re.subn("\d+","",s))
# ('ababcdddabcasdfjlasjdkllkjklklkjkljlkj', 12)
# 修饰符 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))
# [('b', 'd'), ('b', 'd')]
# 有名分组
s = 'abc abcd abcdd'
print(re.search("a(?P<name1>.)c(?P<name2>d)",s).groupdict())
# {'name1': 'b', 'name2': 'd'}
# 超高级用法
s = 'abc123abc123'
print(re.sub("c(\d+)a"," ",s))
# ab bc123
print(re.sub("c(?P<name1>\d+)a"," \g<name1> " ,s))
# ab 123 bc123