subprocess模式,re模式,logging模块, 防止测试自动执行, 包的理论
subprocess模
1.subprocess模块
可以通过python代码给操作系统终端发送命令, 并且可以返回结果。
import subprocess
while True:
1.让用户输入终端命令
cmd_str = input('请输入终端命令:').strip()
Popen(cmd命令, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
调用Popen就会将用户的终端命令发送给本地操作系统的终端
得到一个对象,对象中包含着正确或错误的结果。
obj = subprocess.Popen(
cmd_str, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
success = obj.stdout.read().decode('gbk')
if success:
print(success, '正确的结果')
error = obj.stderr.read().decode('gbk')
if error:
print(error, '错误的结果')
re模块
夺命三问:
1)什么是正则表达式与re模块?
正则表达式:
正则表达式是一门独立的技术, 任何语言都可以使用正则表达式,
正则表达式是由一堆特殊的字符组合而来的。
字符组 - 元字符 - 组合使用
re模块:
在python中,若想使用正则表达式,必须通过re模块来实现。
2)为什么要使用正则?
比如要获取“一堆字符串”中的“某些字符”,
正则表达式可以帮我们过滤,并提取出想要的字符数据。
应用场景:
爬虫: re, BeautifulSoup4, Xpath, selector
数据分析过滤数据: re, pandas, numpy...
用户名与密码、手机认证:检测输入内容的合法性
用户名: na tank
3)如何使用?
import re
re模块三种比较重要的方法:
-
findall(): ----> []
可以匹配 "所有字符" ,拿到返回的结果,返回的结果是一个列表。
-
search():----> obj ----> obj.group()
在匹配一个字符成功后,拿到结果后结束,不往后匹配。。返回的是对象
-
match():----> obj ----> obj.group()
从匹配字符的开头匹配,若开头不是想要的内容,则返回None。。。返回的是对象
例子::: import re str1 = 'awfwaghowiahioawhio' res = re.findall('[a]{1}', str1) print(res) # ['a', 'a', 'a', 'a'] res = re.search('[a]{1}', str1) print(res) print(res.group()) # a res = re.match('[b]{1}', str1) #None print(res)
例子:::
import re
str1 = 'sean tank json'
# findall
res = re.findall('[a-z]{4}', str1)
print(res)
#search
res = re.search('[a-z]{4}', str1)
print(res) # 返回的是对象
print(res.group())
# match
res = re.match('sean', str1)
#可以正常写
print(res)
print(res.group())
#也可一这样写
if res:
print(res.group())
元字符:
*******根据博客的表格来记 (看一眼)
https://images2015.cnblogs.com/blog/1036857/201705/1036857-20170529203214461-666088398.png
^: 代表“开头”
$: 代表“结束”
|: 代表“或”
(13|14): 可以获取一个值,判断是否是13或14.
{1}: 需要获取1个值 限制数量
[]: 分组限制取值范围
[0-9]: 限制只能获取0——9的某一个字符。
- 组合使用
- \w\W: 匹配字母数字下划线与非字母数字下划线,匹配所有。
- \d\D: 无论是数字或者非数字都可以匹配。
- \t: table
- \n: 换行
- \b: 匹配单词结尾,tank jasonk
- ^: startswith
- '^'在外面使用: 表示开头。
- [^]: 表示取反的意思。
- $: endswith
- ^$: 配合使用叫做精准匹配,如何限制一个字符串的长度或者内容。
- |: 或。ab|abc如果第一个条件成立,则abc不会执行,怎么解决,针对这种情况把长的写在前面就好了,一定要将长的放在前面。
- [^...]: 表示取反的意思。
- [^ab]: 代表只去ab以外的字符。
- [^a-z]: 取a-z以外的字符。
logging模块
应用:
1、定义日志的存放地址logfile_path:先定位(创建)日志存放的目录,拼接日志自身的绝对路径,logfile_path就是日志的绝对路径。
2、拷贝日志的配置字典LOGGING_DIC
3、调用生成日志的方法
def get_log(user_type):
logging.config.dictConfig(LOGGING_DIC) # 加载配置字典
logger = logging.getLogger(user_type) # 传参数得到结果
return logger # 返回结果
logger = get_log('user_type')
logger.info('日志消息')
防止测试自动执行
有很多.py文件中封装的全部都是函数,所以没必要加上
if __name__ =='__main__':
如果a.py文件中写了非函数的正常执行语句,并且碰巧又被b.py文件作为模块导入,此时就要注意了,
一定要在a.py文件的正常执行语句前增加上述语句。否则在导入的时候会执行,造成意料之外的内容出现。
# func()
# __name__属于模块名称空间中的一个名字
# 当我们执行该模块时就会产生
在自身执行的时候,__name__ = __main__
在被其他模块调用时,__name__ = 包.模块名
包的理论
导入包的时候发生的事情:
当包被导入的时候,会以包中的__init__.py来产生一个名称空间。。
执行__init__.py文件时,会将__init__.py中的所有名字加载到名称空间中。-->init.py自身文件中的名字
接着,包下所有的模块的名字都会加载到__init__.py产生的名称空间中。-->init.py统辖的模块的名字
导入模块指向的名称空间其实就是__init__.py产生的名称空间中。