【Python random&re&time模块&正则表达式&os模块&sys模块 08】

一、常用模块rendom

什么叫模块?  import time  time这样的就叫模块

模块都是C写的,所有的模块当中也是一对代码,这一对代码引入以后就可以直接使用

模块的分类

  • 内置模块
  • 扩展模块\第三方模块 (比如:django,pandas等)
  • 自定义模块

1、random模块 (随机函数)

随机的规则:在某一个范围中能够抽到每一个值的概率都是相同的

import random
ret=random.random() #0~1之间的随机数
print(ret)

# 100-200之间的随机整数
ret2 = random.randint(100,200)  #-->randint取随机整数,左右都是闭区间【】
print(ret2)

ret3 = random.randrange(100,200,50) #randrange(start,end,end)
print(ret3)

lst = [1,2,3,4,5,6,7]
random.shuffle(lst) #shuffle随机打乱列表内的元素,常用于扑克牌洗牌
print(lst)

ret4 = random.choices([1,2,'zx',[1,2,3]]) #随机取一个值
print(ret4)

ret5 = random.sample([1,2,'alex',[1,2,3]],20)  #随机取多个值
print(ret5)

二、正则表达式

正则表达式 : 只和字符串打交道
    # 第一: 从一大段文字中,获取符合条件的内容
        # 爬虫
    # 第二: 检测某一个字符串,是否完全符合规则
        # 表单的验证
            # 并不会真的请求银行,具体手机,具体的邮件
            # 总是根据一些规则来先判断是否合法

1)字符组

  • 匹配所有数字:[1-9]
  • 匹配所有小写字母:[a-z]
  • 匹配所有大写字母:[A-Z]
  • 匹配所有字母数字:[0-9a-zA-Z],
  •     |-这里的匹配规则只能从ascii码小的值到大的值,可以一次取多个区间:[0-9a-f]   a 的ascii是97  A是64

2)元字符

  •  \d   [0-9]  一样的意思
  •  \w   [0-9a-zA-Z_] 表示:数字字母下划线中文
  •  \s \t \n  匹配所有的空白符\制表符\换行符
  •  \D \W \S 匹配所有非数字\匹配所有非数字字母下划线\匹配所有非空白
  •  .    匹配除了换行符之外的任意一个字符
  •  ^ $  匹配一个字符串的开始,$匹配一个字符串的结束
  • [] [^] 字符组 非字符组
  •  | () 或  用来规范符号的作用域

3)量词

  •  {n}  表示匹配n次
  •  {n,} 表示匹配至少n次
  •  {n,m} 表示最少匹配n次,最多匹配m次
  •  ?    0或1次
  •  +    1-无穷大
  •  *    0-无穷大

#案例:匹配手机号码

1[3-9]\d{9}

#案例:匹配任意一个正整数

[1-9]\d*

#案例:匹配任意一个小数

\d+\.\d+    ===>\d+表示长度的数字  \.是把.转义使用的  

#案例:匹配整数或小数

\d*(\.\d+)?  ===>通过()进行了分组,然后通过?确定要么是整数,要么就是小数,保证10.这样的数字是匹配不上的

注意:

  •  只写元字符  一个元字符表示一位字符上的内容
  •  元字符量词 量词只约束前面的一个元字符\
  •  (元字符元字符)量词   量词只能加一个

所有的正则表达式在工具中如果匹配成功,直接放到r'' 就可以直接使用   --> 意思是防止转义

三、re模块

1)findall、search、match方法

import re
# findall匹配所有匹配项目
ret = re.findall('\d+','hello123,world456')
print(ret) #['123', '456']
# search从头开始往后找,任何地方有符合条件的都返回一个,并且分组后只返回第一个
ret1 = re.search('\d+','hello123,world456')
print(ret1)
print(ret1.group()) #123
# match从头开始匹配,如果开始部分匹配到了匹配成功,如果开始部分没有匹配到就是匹配失败
ret1 = re.match('\d+','123hello123,456world456')
print(ret1)
print(ret1.group()) #123
# findall中的分组优先
ret3 = re.findall('\d+(\.\d+)?','hello123.222,world456.555')
print(ret3)#['.222', '.555']
'''
执行的结果为什么会出现这种情况,其实findall会把123.222和456.555都取出来,
但是由于分组优先的规则所以把.后面的内容取出来了,
那么如何解决?
'''
ret4 = re.findall('\d+(?:\.\d+)?','hello123.222,world456.555')
print(ret4) #['123.222', '456.555']
'''只需要在\.前面加上?:即可解决'''

#案例:手机号码的验证

import re
phone = input('请输入手机号码:')
regex = r'^1[2-9]\d{9}$'
ret = re.search(regex,phone)
if ret:
    print('手机号是合法的 %s'%phone)
else:
    print('手机号是不合法的!')

如果用match,regex=r'1[2-9]\d{9}$' regex中就不需要^

#了解内容:根据正则进行切割

ret = re.split(r'\d+',r'alex84wusir78')
print(ret)

2)sub 替换方法

# sub替换方法 语法:sub(正则表达式,要替换的内容,待替换的字符串,替换的个数)
ret = re.sub(r'\d','W','alex789wusir234',1)
print(ret) #alexW89wusir234

3)subn 替换方法

# subn替换方法2 返回值是一个元组,第一项是结果,第二项是替换次数
ret = re.subn(r'\d+','W','alex789wusir234',2)
print(ret) #('alexWwusirW', 2)

四、os模块

  • os.path.getsize(绝对路径)  获取文件的大小,但是不能获取文件夹的准确大小
  • os.path.isfile(绝对路径)  判断是否是文件
  • os.path.isdir(绝对路径) 判断是否是文件夹
  • os.path.join(文件夹的名字,名字) 跨平台的文件路径的拼接
  • os.listdir('文件夹的名字') 显示这个文件夹下的所有名字(包括文件和文件夹)

#案例:计算文件夹的大小

import os

def path_size(path):
    # 判断是不是文件夹
    if os.path.isdir(path):
        sum_size = 0
        # 获取path路径下文件的名称,最终生成的是一个列表
        dir_name = os.listdir(path)
        # 遍历列表
        for name in dir_name:
            # 把列表和路径拼接在一起
            file_path = os.path.join(path,name)
            # 如果是一个文件,则计算所有文件的大小并相加求和,否则(文件夹)利用递归再次进行剥离计算此文件夹路径下的文件大小
            print(file_path)
            if os.path.isfile(file_path):
                sum_size +=os.path.getsize(file_path)
            else:
                path_size(file_path)
        return sum_size
    #判断是文件,然后计算文件大小
    elif os.path.isfile(path):
        # print('这是一个文件')
        return os.path.getsize(path)
    else:
        print('这不是一个文件或文件夹')

path1 = r'/Users/wufq/Documents/pythonSenio/day03'
path2 = r'/Users/wufq/Documents/pythonSenio/day03/eval和exec函数.py'
path3 = r'/Users/wufq/Documents/pythonSenio/day03/dir1/dir_son1'

ret1 = path_size(path3)
print(ret1)

 os

os.path

#举例:

path = r'/Users/wufq/Documents/pythonSenio/day03/eval和exec函数.py'
ret = os.path.split(path)
ret1 = os.path.split(r'/Users/wufq/Documents/pythonSenio/day03')
print('split1------>',ret)
print('split2------>',ret1)

ret = os.path.dirname(path)
print('dirname------>',ret)
ret = os.path.basename(path)
print('basename------->',ret)

执行结果:

split1------> ('/Users/wufq/Documents/pythonSenio/day03', 'eval和exec函数.py')
split2------> ('/Users/wufq/Documents/pythonSenio', 'day03')
dirname------> /Users/wufq/Documents/pythonSenio/day03
basename-------> eval和exec函数.py

注意:os.path.split  切割路径形成元组,但是永远切割的是最后一个内容,比如路径最后一个是eval和exec函数.py,那么切割是就会切成结果1这样子,如果路径最后一个是day03,那么切割时就会切成结果2的样子,反正就会把最后一个元素切出来,分成两半,dirname取split切割后路径的第一个元素,basename取split切割后路径的第二个元素

五、时间模块

5.1、time模块

# 1、时间戳时间 -->1970年截止到当前时间
ret = time.time()
print(ret)
# 2、结构化时间  tm_isdst:夏令时
ret1 = time.localtime()
print(ret1) #time.struct_time(tm_year=2022, tm_mon=5, tm_mday=4, tm_hour=11, tm_min=49, tm_sec=49, tm_wday=2, tm_yday=124, tm_isdst=0)
# 格式化时间 --->time模块的格式化不识别中文
ret2=time.strftime('%Y-%m-%d %H:%M:%S')
print(ret2) #2022-05-04 11:58:05

 三种格式之间的转换  -->会这三种转换就可以了 

# 案例:三种时间格式相互转换

# 字符串-->时间戳
str_time = '20220501 12:20:10'
struct_time = time.strptime(str_time,'%Y%m%d %H:%M:%S') #注意:%Y%m%d这个格式必须和需要转换的字符串内时间的格式保持一致

# 结构化-->时间戳
time_stamp = time.mktime(struct_time) print('字符串-->时间戳:',time_stamp) # 时间戳-->结构化时间 time_stamp1= 2000000000 struct_time1 = time.localtime(time_stamp1) print('时间戳-->结构化时间:',struct_time1) # 结构化时间-->字符串 struct_time2 = time.localtime() str_time1 = time.strftime('%Y-%m-%d %H:%M:%S',struct_time2) print('结构化时间-->字符串:',str_time1) 执行时间: 字符串-->时间戳: 1651378810.0 时间戳-->结构化时间: time.struct_time(tm_year=2033, tm_mon=5, tm_mday=18, tm_hour=11, tm_min=33, tm_sec=20, tm_wday=2, tm_yday=138, tm_isdst=0) 结构化时间-->字符串: 2022-05-04 13:34:24

5.2、datetime模块   -->好处就是可以做时间运算

from datetime import datetime
# 1、获取当前时间:datetime.now()
now_time = datetime.now()
print('当前时间:',now_time)
# 2、获取当前格林威治时间
t_time = datetime.utcnow()
print('格林威治时间:',t_time)
# 3、datetime的另外一种便捷用法:单独获取年,月 日等
print('年:',now_time.year)
print('月:',now_time.month)
print('日:',now_time.day)
# 4、创建一个指定的时间
dt = datetime(2022, 10, 1, 12, 20, 30)
print('自定义设置日期格式:',dt)

执行结果:
当前时间: 2022-05-04 14:01:50.802844
格林威治时间: 2022-05-04 06:01:50.802892
年: 2022
月: 5
日: 4
自定义设置日期格式: 2022-10-01 12:20:3

|-- 字符串转datetime格式 ,用strptime

s1 = '2017/9/30'
dt1 = datetime.strptime(s1,'%Y/%m/%d')
print(dt1) #2017-09-30 00:00:00

|-- datetime格式转字符串,用strftime

dt2 = datetime(2019, 8, 11, 17, 8,0)
ret2 = dt2.strftime('%Y年%m月%d日 %H点%M分')
print(ret2) #2019年08月11日 17点08分

# 应用场景:用数据库里面取出来时间,然后转换成字符串进行操作

# 案例1:算当前月的1号对应的0点的时间戳时间

import time
def get_stamp():
    strt = time.strftime('%Y-%m-01 00:00:00')
    # print(strt) #2022-05-01 00:00:00
    stru = time.strptime(strt,'%Y-%m-%d %H:%M:%S')
    stamp = time.mktime(stru)
    return stamp

time_1=get_stamp()
print(time_1)

#案例2:t2的时间 t1的时间 t2-t1经历了多少年 月 日 时 分 秒

'''
思路:
1、把t1,t2的时间转换成时间戳
2、两个时间戳相减,得到的也是一个时间戳
3、把相减的时间戳在转换成结构化时间
'''
t1 = '2017-7-11 11:11:11'
t2 = '2019-9-03 08:43:07'
def sub_time(t1,t2):
    stru_t1 = time.strptime(t1,'%Y-%m-%d %H:%M:%S')
    stamp_t1 = time.mktime(stru_t1)
    stru_t2 = time.strptime(t2, '%Y-%m-%d %H:%M:%S')
    stamp_t2 = time.mktime(stru_t2)
    #abs是求绝对值  -->原因:t1,t2并不清楚谁大谁小,所以求个绝对值
    stamp_t2t1 = abs(stamp_t2-stamp_t1)
    stru_t2t1 = time.gmtime(stamp_t2t1)
    # stru_t2t1这个值是从1970年1月1号截止到现在的时间,所以需要减去1970 1 1号才能算出来t1,t2相差了多少
    return (stru_t2t1.tm_year - 1970, stru_t2t1.tm_mon - 1, stru_t2t1.tm_mday - 1, stru_t2t1.tm_hour, stru_t2t1.tm_min,
            stru_t2t1.tm_sec)

ret = sub_time(t1,t2)
print(ret) #(2, 1, 22, 21, 31, 56)

六、sys模块

1、sys.modules

  • sys.modules 描述的是当前执行代码位置,解释器中导入的所有模块都会被放到字典中
  • 字典的key就是模块的名字,对应的value是这个模块对应的在内存中的位置
import time
import sys
'''
因为sys.modules解释器中会把导入的所有模块都存到字典中,而字典的key就是模块的名字,value是模块的内存地址
所以直接可以通过sys.modules['time'] 这种字典的key来取value,然后调用对应的方法
比如:sys.modules['time'].time()== time.time()  他两就完全是一样的
'''
print(sys.modules['time'].time()== time.time()) #True

2、sys.path

  • 能不能导入一个模块就要看这个模块所在的路径在不在sys.path中
  • 如果在sys.path中寻找数据的时候,能够找到一个文件,那么就不继续往下走了
  • pycharm会自动的把当前的项目路径添加到sys.path中来,在实际的生产环境中不应该出现这个值

3、sys.argv

  • 在执行当前文件的时候传递一些参数到python代码中来

 

posted @ 2022-04-26 20:23  尘封~~  阅读(55)  评论(0编辑  收藏  举报