1 2 3 4

模块三

模块三

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模块?

​ -正则表达式:

​ 正则表达式是一门独立的技术,任何语言都可以使用则会功能则表达式。

​ 正则表达式是有一堆特殊的字符组合而来的。

​ -字符组

​ -元字符

​ ---组合使用

​ -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

上面的例子就是在当前模块下面测试执行功能
如果在另外一个文件中执行这个模块的
因为是测试了,返回的结果是
模块名字,
如果没有执行测试的功能,则这个结果是打印模块的内容

posted @ 2019-11-23 17:18  ^更上一层楼$  阅读(147)  评论(0编辑  收藏  举报