目录
模块三
1.subprocess
2.re 模块和正则表达式
2.2re 模式的三种比较重要的方法:
3 包的介绍
防止导入模块时自动执行测试功能
模块三
1.subprocess
- 可以通过 python 代码给操作系统终端发送命令, 并且可以返回结果.
? sub: 子
? process: 进程
- import subprocess
- while True:
- cmd_str = input('请输入终端的命令:').strip()# 这个. strip()的作用就是默认去空格的
- obj = subprocess.Popen(cmd_str,
- shell = True,
- stdout = subprocess.PIPE,
- stderr = subprocess.PIPE
- )
- #shell 指的是帮我们连接一个本地电脑或者远程电脑
- #调用 pope 就会将用户的终端命令发送到本地的操作系统的终端,
- #得到一个对象, 对象中包含着正确或者错误的结果
- success = obj.stdout.read().decode('gbk')
- if success:
- print(success,'打印正确')
- error = obj.stderr.read().decode('gbk')
- if error:
- print(error,'打印错误')
- >>>>>>>>>
比如可以输入 dir 等终端命令
2.re 模块和正则表达式
- 什么正则表达式 与 re 模块?
? - 正则表达式:
? 正则表达式是一门独立的技术, 任何语言都可以使用则会功能则表达式.
? 正则表达式是有一堆特殊的字符组合而来的.
? - 字符组
? - 元字符
? --- 组合使用
? 在 python 中, 如果想使用正则表达式, 必须通过 re 模块来实现.
- 为什么使用正则?
? 比如要获取一堆字符串中的某些字符, 正则表达式可以帮我们过滤, 并提取出想要的字符数据.
1, 检测手机号码的合法性:
- # 纯 python 校验
- # 需求: 11 位, 开头 13/14/15/19
- import re
- while True:
- phone_number = input('请输入你的手机号码:').strip()
- #not> and> or
- if len(phone_number) == 11 and (phone_number.startswith(
- '13'
- ) or phone_number.startswith(
- '14'
- ) or phone_number.startswith(
- '18'
- )
- ):
- print('手机合法')
- break
- else:
- print('手机号码不合法')
- >>>>>>>>>>>>
请输入你的手机号码: 18755073689
手机合法
- ### 正则表达式的的代码
- #11 位 开头 13/14/15/18
- #参数 1 正则表达式
- #参数 2 需要过滤的表达式
- # ^ 代表开头 $ 表示结束 ,| 是或的意思,(13|14)可以获取一个值, 判断是 13 还是 14
- #{1}获取一个值, 限制数量
- #[]分组限制取值范围 [0,9]限制只能获取一个 0-9 之间的某一个字符
- import re
- while True:
- phone_number = input('请输入你的手机号码:').strip()
- if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
- print('合法') ##### 一共需要的是 11 为 号码的前面的 2 位已经确认了, 现在还需要 9 位
[0-9]提供了一个范围, 只能 10 个数字内取, 并且这个后面的 {9} 代表 要 9 位
- break
- else:
- print('不合法')
- >>>>>>>>>>>>>>
请输入你的手机号码: 18755073689
合法
正则表达的式
- '''
- - 字符组:
- - [0-9] 可以匹配到一个 0-9 的字符
- - [9-0]: 报错, 必须从小到大
- - [a-z]: 从小写的 a-z
- - [A-Z]: 从大写 A-Z
- - [z-A]: 错误, 只能从小到大, 根据 ascii 表来匹配大小.
- - [A-z]: 总大写的 A 到小写的 z.
- 注意: 顺序必须要按照 ASCII 码数值的顺序编写.
- import re
- res = re.match('[A-Za-z0-9]{8}','Tank3467')
- print(res)
- >>>>>>>>
- <_sre.SRE_Match object; span=(0, 8), match='Tank3467'>
- - 元字符:
- ******* 根据博客的表格来记 (看一眼)
- https://images2015.cnblogs.com/blog/1036857/201705/1036857-20170529203214461-666088398.png
- - 组合使用
- - \w\W: 匹配字母数字下划线与非字母数字下划线, 匹配所有.
- - \d\D: 无论是数字或者非数字都可以匹配.
- - \t: table
- - \n: 换行
- - \b: 匹配单词结尾, tank jasonk
- - ^: startswith
- - '^'在外面使用: 表示开头.
- - [^]: 表示取反的意思.
- - $: endswith
- - ^$: 配合使用叫做精准匹配, 如何限制一个字符串的长度或者内容.
- - |: 或. ab|abc 如果第一个条件成立, 则 abc 不会执行, 怎么解决, 针对这种情况把长的写在前面就好了, 一定要将长的放在前面.
- - [^...]: 表示取反的意思.
- - [^ab]: 代表只去 ab 以外的字符.
- - [^a-z]: 取 a-z 以外的字符.
- 2.2re 模式的三种比较重要的方法:
- -findall():--- ---->[]
- 可以匹配所有的字符, 拿到的返回结果是一个列表.#### 比较常用
- import re
- res = 'agjgjeljkbgljgg'
- t = re.findall('[a-z]{4}',res)
- print(t)
- >>>>>>>>
- ['agjg', 'jelj', 'kbgl']### 返回的是一个列表
- #########
- str3 = "not 404 found 张全蛋 99 广州"
- res = re.findall('(张全蛋 | 广州)',str3)
- print(res)
- >>>>>>>
- ['张全蛋', '广州']
- source = '''
- <html><h1>www.baidu.com</h1></HTML>
- <HTML><h1>www.taobao.com</h1></HTML>
- <HTML><h1>www.jd.com</h1></HTML>
- <HTML><h1>www.oldboyedu.com</h1></HTML>
- '''res = re.findall('www.*?com',source)
- print(res)
- >>>>>>>
- ['www.baidu.com', 'www.taobao.com', 'www.jd.com', 'www.oldboyedu.com']
- -search():------>obj------->obj.group()
- 在匹配一个字符成功后, 拿到结果后, 不往后匹配
- import re
- res = 'agjgjeljkbgl'
- l1 = re.search('[a-z]{4}',res)
- print(l1)
- print(l1.group()) #### 这个操作后才可以返回结果
- >>>>>>>>>>>
- <_sre.SRE_Match object; span=(0, 4), match='agjg'>
- agjg
- -match()------>obj------->obj.group()
- 从匹配字符的 开头开始, 如果开头的不是想要的内容, 则返回 None
- res = '111111agjgjeljkbgl'#### 开头不是想要的内容
- l2 = re.match('[a-z]{4}',res)
- print(l2)
- >>>>>>>
- None
- res = 'agjgjeljkbgl'##### 开头是想要的内容
- l2 = re.match('[a-z]{4}',res)
- print(l2)
- print(l2.group())
- >>>>>>>>>
- <_sre.SRE_Match object; span=(0, 4), match='agjg'>
- agjg
- # logging 的配置信息
- """
logging 配置
- """
- import os
- import logging.config####logging 是一个包
- # 定义三种日志输出格式 开始 ####'%s' % (name) 另外一种方式:%(names
- standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' '[%(levelname)s][%(message)s]' #其中 name 为 getlogger 指定的名字
- simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
- id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
- # 定义日志输出格式 结束
- # **************** 注意 1: log 文件的目录
- BASE_PATH = os.path.dirname(os.path.dirname(__file__))
- logfile_dir = os.path.join(BASE_PATH, 'log_dir')#### 同时需要新建一个 log_dir 文件 夹
- # print(logfile_dir) #####lofile_dtr 这个是一个'包'
- # **************** 注意 2: log 文件名
- logfile_name = 'user.log'
- # 如果不存在定义的日志目录就创建一个
- if not os.path.isdir(logfile_dir):
- os.mkdir(logfile_dir)
- # log 文件的全路径
- logfile_path = os.path.join(logfile_dir, logfile_name)
- # **************** 注意 3: log 配置字典
- LOGGING_DIC = {
- 'version': 1,
- 'disable_existing_loggers': False,
- 'formatters': {
- 'standard': {
- 'format': standard_format
- },
- 'simple': {
- 'format': simple_format
- },
- },
- 'filters': {},
- 'handlers': {
- #打印到终端的日志
- 'console': {
- 'level': 'DEBUG',
- 'class': 'logging.StreamHandler', # 打印到屏幕
- 'formatter': 'simple'
- },
- # 打印到文件的日志, 收集 info 及以上的日志
- 'default': {
- 'level': 'DEBUG',
- 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
- 'formatter': 'standard',
- 'filename': logfile_path, # 日志文件
- 'maxBytes': 1024*1024*5, # 日志大小 5M
- 'backupCount': 5,
- 'encoding': 'utf-8', # 日志文件的编码, 再也不用担心中文 log 乱码了
- },
- },
- 'loggers': {
- #logging.getLogger(__name__)拿到的 logger 配置
- '': {
- 'handlers': ['default', 'console'], # 这里把上面定义的两个 handler 都加上, 即 log 数据既写入文件又打印到屏幕
- 'level': 'DEBUG',
- 'propagate': True, # 向上 (更高 level 的 logger) 传递
- },
- },
- }
- # 注意 4:
- def get_logger(user_type):
- # 1. 加载 log 配置字典到 logging 模块的配置中
- logging.config.dictConfig(LOGGING_DIC)
- # 2. 获取日志对象
- # logger = logging.getLogger('user')
- # logger = logging.getLogger('bank')
- # logger = logging.getLogger('shop')
- logger = logging.getLogger(user_type)
- return logger
- # logging.config.dictConfig(LOGGING_DIC)
- # # 调用获取日志函数的到日志对象
- # logger = logging.getLogger('user')
- # 通过 logger 日志对象, 调用内部的日志打印
- logger = get_logger('user')
- # '只要思想不滑坡, 方法总比问题多!'就是需要记录的日志信息
- logger.info('学习不要浮躁, 一步一个脚印!')
- # logger.info('只要思想不滑坡, 方法总比问题多!')
3 包的介绍
3.1 什么是包?
? - 包是一个带有__init__.py 的文件夹, 把也可以被导入, 并且可以一并导入包下的所有模块.
3.2 为什么要使用包?
? - 包可以帮助我们管理, 模块, 在包中有一个__init__.py 由他来管理模块
3.3 怎么样使用模块?
? -import 包. 模块名
? -import. 模块. 名字
? -from 包 import 模块名
? -from 包. 模块名 import 模块中名字
3.4 导入包时发生的事情:
? 1. 当包被导入时, 会以包中的 --init--.py 来产生一个名称空间.
? 2. 然后执行 --init--.py 文件, 会将 --init--.py 中所有的名字添加到名称空间中.
? 3. 在执行文件中使用包中的模块的时候, 指向的是 --init--.pyde 名称空间
防止导入模块时自动执行测试功能
- def func():
- print('from the world')
- if __name__ == '__main__':
- print('在当前的模块下执行测试功能')
- func()
- else:
- print('当前的模块已经被导入了')
- # __name__是模块名称空间里面的一个名字,
- # 当我们在执行该模块的时候就会产生
- # ------>main + 回车键就会产生下面的这个
- # if __name__ == '__main__':
- >>>>>>>>>>>>
在当前的模块下执行测试功能
from the world
上面的例子就是在当前模块下面测试执行功能
如果在另外一个文件中执行这个模块的
因为是测试了, 返回的结果是
模块名字,
如果没有执行测试的功能, 则这个结果是打印模块的内容
模块三
来源: http://www.bubuko.com/infodetail-3300692.html