python学习笔记day8(模块初始)

一模块介绍

 1.模块
 # 为什么要有模块
    # python其实有很多现成的方法,但是这些函数不能全都放在内存里
    # 为用户节省很多不必要的内存消耗
    # 用不到的功能就不用导入到内存里了
 2. 模块是什么
    # 一块python代码
    # 一组python代码
    # 一组C语言的代码
    # 一堆写好的 现成可以用的 函数、类
    # 以功能来分类的
 3. 模块有哪几类
    # 内置模块 —— 随着python解释器的安装直接可以使用的模块
    # 扩展模块 —— 需要你自己安装一下才能使用的模块 django itchat
    # 自定义模块 —— 用户根据自己的需求完成的一组功能


 二.正则表达式概述

 引入:在开发中会有大量的字符串处理工作,其中经常会涉及到字符串格式的校验,例如有一下场景:

 1).如何判断一个字符串是手机号:

  

 2).在一个文件中如何找出以“itcast”开头的语句:

  

 3).在一个文件中,找到含有“itcast”的语句:

  

 4).在一个文件中找到含有126或者163的所有邮箱地址。

 1.正则模块介绍:

  正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。Regular Expression的“Regular”一般被译为“正则”、“正规”、“常规”。此处的“Regular”即是“规则”、“规律”的意思,Regular Expression即“描述某种规则的表达式”之意。

  2.re模块的操作:

  在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re

   (1).re模块的使用过程:

#导入re模块包
import re
#匹配规则
ret = re.match("正则表达式规则","要匹配的字符串")
#如果匹配的到,就用group()来取值
ret.group()
re模块的使用过程

   re.match是用来进行正则匹配检查的方法,若字符串匹配正则表达式,则match方法返回匹配对象(Match Object),否则返回None(注意不是空字符串"")。匹配对象Macth Object具有group方法,用来返回字符串的匹配部分。

  (2).re模块示例,匹配hello开头的字符串:

#导入re模块包
import re
#匹配规则
ret = re.match("hello","hello world")
#如果匹配的到,就用group()来取值
print(ret.group())
匹配hello开头

  re.match() 能够匹配出以xxx开头的字符串

 3.表示字符:

  在上述中,我们了解到通过re模块能够完成使用正则表达式来匹配字符串,这里将要讲解正则表达式的单字符匹配,请看以下字符及功能:

  

  示例一: . 的用法:

import re
ret = re.match(".","M")
print(ret.group())
ret1 = re.match(".","m")
print(ret1.group())
ret2 = re.match(".","3")
print(ret2.group())
"."的用法

  可以看到.能匹配任意字符,因此本例将匹配到的都打印了出来

    示例二:[ ]的用法:

import re
#匹配小写字母h
ret = re.match("h","hello")
print(ret.group())      #h
#匹配大写字母H
ret1 = re.match("H","Hello")
print(ret1.group())     #H
#如果同时匹配大小写字符可以用[]
ret2 = re.match("[hH]","hello")
print(ret2.group())     #h
#如果同时匹配大小写字符可以用[]
ret3 = re.match("[HH]","Hello")
print(ret3.group())     #H
#匹配0-9之间的数字第一种写法
ret4 = re.match("[0123456789]","6")
print(ret4.group())     #6
#匹配0-9之间的数字第二种写法
ret5 = re.match("[0-9]","6")
print(ret5.group())     #6
[]的用法

  示例三:\d的用法:

import re
#匹配一个数字
ret = re.match("\d","2333")
print(ret.group())  #2
#连续匹配多个数字
ret1 = re.match("\d\d\d","233333")
print(ret1.group())  #233
#匹配含有中文的数字
ret2 = re.match("嫦娥\d号","嫦娥1号发射成功")
print(ret2.group())   #嫦娥1号
\d的用法

  其他的匹配符这里暂时不一一列出。

 4.原始字符串:

import re
mm = "d:\\a\\b\\c"
print(mm)       #d:\a\b\c
print(re.match("d:\\\\",mm).group())  #d:\
print(re.match("d:\\\\a",mm).group()) #d:\a
#注意这里加上了r表示原始字符串
print(re.match(r"d:\\a",mm).group())  #d:\a
r:原始字符串

  Python中字符串前面加上 r 表示原生字符串,与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,有了原始字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

 5.表示数量:

  匹配多个字符的相关格式:

  

  需求一:匹配出,一个字符串第一个字母为大小字符,后面都是小写字母并且这些小写字母可有可无:

import  re
ret = re.match("[A-Z][a-z]*","Dog")
print(ret.group())   #Dog
View Code

  需求二:匹配出,变量名是否有效

#匹配变量名:由字母数字下划线组成,不能由数字开头
import re
ret = re.match("[a-zA-Z_]+[\w_]*","name_1")
print(ret.group())
View Code

  需求三:匹配出,0到99之间的数字

#匹配0-99之间的数字
import re
ret = re.match("[0-9]?[0-9]","99")
print(ret.group())
View Code

  需求四:匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线

#需求:匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线
import re
ret = re.match("[a-zA-Z\d_]{8,20}","dwfwfg345erg_fdweagseggbghsrghr")
print(ret.group())
View Code

  练一练:匹配出163的邮箱地址,且@符号之前有4到20位

#练一练:匹配出163的邮箱地址,且@符号之前有4到20位
import re
ret = re.match("[a-zA-Z\d_]{4,20}@163\.com","hel2_lo@163.com")
print(ret.group())
View Code

 6.表示边界:

  

  示例一:利用$匹配163地址:

import re
ret = re.match("[a-zA-Z\d_]{4,20}@163\.com","hel2_lo@163.comewawe")
print(ret.group())   #注意匹配出的不合格
ret1 = re.match("[a-zA-Z\d_]{4,20}@163\.com$","hello@163.com")
print(ret1.group())  #用$来表示以com结尾进行匹配,匹配不到则报错
View Code

  示例二:利用\b匹配单词的边界:

import re
ret = re.match(r".*\bver\b","ho ver er")
print(ret.group())   #ho ver
ret1 = re.match(r"\bver\b","ver er")
print(ret1.group())  #ver
View Code

  示例三:利用\B匹配非单词的边界:

import re
ret = re.match(r".*\Bver\B","howvertest")
print(ret.group())
View Code

 7.匹配分组:

  

  示例一:| 需求:匹配0-100之间的数字:

import re
ret = re.match("[1-9]?\d$|100","10")
print(ret.group())   #10
ret1 = re.match("[1-9]?\d$|100","100")
print(ret1.group())  #100
View Code

  示例二:() 需求:匹配出163、126、qq邮箱之间的数字.

import re
ret = re.match("\w{4,20}@(163|126|qq)\.com$","hedllo@163.com")
print(ret.group())
View Code

  示例三:\需求:匹配出<html>hh</html>

#匹配出<html>hh</html>
import re
ret = re.match(r"<([a-zA-Z]*)>\w*</\1>","<html>hh</html>")
print(ret.group())    #<html>hh</html>
View Code

  示例四:\number需求: 匹配出<html><h1>www.itcast.cn</h1></html>

import re
ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>","<html><h1>www.itcast.cn</h1></html>")
print(ret.group())    #<html><h1>www.itcast.cn</h1></html>
View Code

  示例五:(?P<name>)需求:匹配出<html><h1>www.itcast.cn</h1></html>

import re
ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h1></html>")   #注意P大写
print(ret.group())
View Code

 8.re模块的高级用法:

    示例一:利用search匹配文章阅读次数:

import re
ret = re.search(r"\d+","阅读次数,9999")
print(ret.group())
View Code

  示例二:利用findall统计出python、c、c++相应文章阅读的次数

import re
ret = re.findall(r"\d+","python=122,c++=11,c=999")
print(ret)
View Code

  示例三:利用sub将匹配到的阅读次数+1

import re
ret = re.sub(r"\d+","998","python=997")
print(ret)
View Code

  示例四:subn 替换并返回替换的次数

import re
ret = re.subn("\d+","|","adf23234dwer3fwef3")
print(ret)
View Code

  示例五:利用split切割字符串

import re
ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret)   #['info', 'xiaoZhang', '33', 'shandong']
View Code

  示例六:利用compile将正则表达式编译成对象

import re
obj = re.compile("\d{3}") #将正则表达式编译成一个正则表达式对象,规则是要匹配的三个数字
ret = obj.search("abc123eeeee") #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())   #结果123
ret = obj.findall("abc123ee7163has93629") #正则表达式对象调用search,参数为待匹配的字符串
print(ret)
View Code

  示例七:finditer方法的简单使用

import re
ret = re.finditer("\d","day09dnefh23234")
print(ret)
print(next(ret).group())
for i in ret:
    print(i.group())
View Code

  示例八:利用split分隔

import re
ret = re.split("\|","ab2|aaa")
print(ret)
View Code

  9.贪婪模式和非贪婪模式

  Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。

import re
s="This is a number 234-235-22-423"
ret = re.match(".+(\d+-\d+-\d+-\d+)",s)
print(ret.group(1))   #默认贪婪
ret1 = re.match(".+?(\d+-\d+-\d+-\d+)",s)
print(ret1.group(1))  #加?表示非贪婪
贪婪模式

  正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。


 三.collections模块

 1.使用模块必须先导入 # 需要注意的是 已知的所有模块名都不可以作为python文件名 每一个模块都有一个大致的功能,collections给我们提供了一些额外的数据类型str int list dict tuple set float  内置数据类型,每一个类都是一个数据类型 自定义数据类型。

  例如 a = "a"  其实就是实例化一个a的对象,好比 a = str("a") ;a = 1 同理也是一样,在python 中一切皆对象。

  有这样一个案例:p=(1,2) 看到这个数组,大家首先想到的应该是xy轴坐标,那我们如何求原点到此坐标点之间的距离呢?这里引入math模块的sqrt方法:

from math import sqrt
p = (1,2)
print(sqrt(p[0]**2 + p[1]**2))  #2.236067977。。。
View Code

  按照上述这个方法就求出了结果?但是大家有没有发现这样一个问题,这样的代码可读性很差。那么接下来我们引入collections模块来计算此结果:

import collections
from math import sqrt
p = (1,2)
Point = collections.namedtuple("point",["x","y"])
p = Point(1,2)
# print(p)
# print(p.x)
# print(p.y)
print(sqrt(p.x**2 + p.y**2))
View Code

  如上程序相信大家一看肯定眼前一亮,即见名知意,而且代码可读性又很高。

 2.queue和栈的队列

  在存储数据的基础上 严格的维持了一个秩序,数据的进出顺序。

  queue队列:先进来的先出去 ----类比售票

  栈的队列:先进来的后出去 ----计算机的计算方法

import queue
q = queue.Queue()
l = list()
q.put(1)  #放进去
q.put(2)  #放进去
print(q.get()) #取出来
print(q.get()) #取出来
queue队列

 3.追加:

import collections
dq = collections.deque()
dq.append(1)
dq.append(2)
print(dq)   #deque([1, 2])
print(dq.pop()) #2
print(dq)  #deque([1])
dq.appendleft(5)
print(dq.popleft()) #5
print(dq) #deque([1])
View Code

 有序字典:

d = dict([("a",1),("b",2),("c",3)])
print(d.keys())
from collections import OrderedDict
d = OrderedDict([("a",1),("b",2),("c",3)])
print(d.keys())
有序字典

 默认字典:

from collections import defaultdict
dd = defaultdict(list)
print(dd)
dd["aaaaaaaa"].append(1)
print(dd)
# def func():return  5
dd = defaultdict(lambda :5)
print(dd)
dd["aaaaaaaa"]
print(dd)
dd["aaaaaaaa"] = 20
print(dd)
默认字典

 4.callable方法:

a = 1
class B():pass
def c():pass
print(callable(a))  #False
print(callable(B))  #True
print(callable(c))  #True
callable

 四.time模块

 1.和时间有关系,我们就要用到时间模块,在用之前需要先导入time模块,如下:

#导入时间模块
import time
#程序阻塞三秒
time.sleep(3)
#获取当前的时间戳
print(time.time())  #1530796512.0110383
时间

  在Python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:

  (1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。

  (2)格式化的时间字符串(Format String): ‘1999-12-06’

%y 两位数的年份表示(00-99%Y 四位数的年份表示(000-9999%m 月份(01-12%d 月内中的一天(0-31%H 24小时制小时数(0-23%I 12小时制小时数(01-12%M 分钟数(00=59%S 秒(00-59%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
View Code

  (3)元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)

  

  首先,我们先导入time模块,来认识一下python中表示时间的几种格式:

#导入时间模块
import time
#时间戳
print(time.time())
#时间字符串
print(time.strftime("%Y-%m-%d %X"))
print(time.strftime("%Y-%m-%d %H-%M-%S"))
#时间元组:localtime将一个时间戳转换为当前时区的struct_time
print(time.localtime())
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24,tm_hour=13, tm_min=59, tm_sec=37,tm_wday=0, tm_yday=205, tm_isdst=0)
View Code

  小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的

  (4).几种时间格式之间的转换

  

#时间戳-->结构化时间
#time.gmtime(时间戳)    #UTC时间,与英国伦敦当地时间一致
#time.localtime(时间戳) #当地时间。例如我们现在在北京执行这个方法:与UTC时间相差8小时,UTC时间+8小时 = 北京时间 
>>>time.gmtime(1500000000)
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
>>>time.localtime(1500000000)
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)

#结构化时间-->时间戳 
#time.mktime(结构化时间)
>>>time_tuple = time.localtime(1500000000)
>>>time.mktime(time_tuple)
1500000000.0
时间格式的相互转换
#结构化时间-->字符串时间
#time.strftime("格式定义","结构化时间")  结构化时间参数若不传,则现实当前时间
>>>time.strftime("%Y-%m-%d %X")
'2017-07-24 14:55:36'
>>>time.strftime("%Y-%m-%d",time.localtime(1500000000))
'2017-07-14'

#字符串时间-->结构化时间
#time.strptime(时间字符串,字符串对应格式)
>>>time.strptime("2017-03-16","%Y-%m-%d")
time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)
>>>time.strptime("07/24/2017","%m/%d/%Y")
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)
时间格式的相互转换

 五.random模块

 1.使用示例:

import random
#随机小数
print(random.random()) #生成大于0小于1之间的小数
print(random.uniform(1,3)) #大于1小于3的小数
#随机整数
print(random.randint(1,5)) #大于等于1且小于等于5之间的整数
print(random.randrange(1,10,2)) #大于等于1且小于10之间的奇数
#随机选择一个返回
print(random.choice([1,"23,[4,5]"]))  #1或者23或者[4,5]
#随机选择多个返回,返回的个数为函数的第二个参数
print(random.sample([1,"23",[4,5]],2)) #列表元素任意2个组合
#打乱列表顺序
item = [1,3,5,7,9]
random.shuffle(item)
print(item)
random

 2.发红包案例:

随机发红包案例  100元 随机分5份
def redPacket(all_money,all_num):
    import random
    list_packet = []
    all_money = all_money*100  #1元换算成分100分
    money = 0
    j = 1
    for i in range(1,all_num):
        list_money = random.randint(1,(all_money-(all_num-i)-money))
        list_packet.append(list_money/100)
        money += list_money
    list_packet.append((all_money-money)/100)
    for i in list_packet:
        print("序号【%d】:您当前抢到的红包金额为:%s元"%(j,i))
        j +=1
if __name__ == "__main__":
    redPacket(100,5)
发红包

六.sys模块

 1.sys模块是和python解释器打交道的,你的模块能不能被顺利的导入,取决于这个模块是否在你的sys.path路径中,路径的寻找是依据sys.path列表中的顺序查找的,找到一个符合条件的就停止了。

    sys.modules 记载了我们已经导入的这个模块已经这个模块的内存地址

import sys
import time
print(sys.modules)
View Code

  sys.argv 命令行参数List,第一个元素是程序本身路径,可通过sys.argv[1].sys.argv[2]取值。

import sys
print(sys.version)  #获得python解释器的版本
print(sys.path)  #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
print(sys.platform)  #返回操作系统的平台名称
View Code

 七.os模块

 1.os模块是与操作系统打交道的,是与操作系统交互的一个接口

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息
os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  运行shell命令,直接显示
os.popen("bash command).read()  运行shell命令,获取执行结果
os.environ  获取系统环境变量

os.path

os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。
                        即os.path.split(path)的第二个元素
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是绝对路径,返回True
os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)  返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
os模块

 

posted @ 2018-07-04 17:12  淋汐去水  阅读(123)  评论(0)    收藏  举报