Python基础之模块

一、模块介绍

Python Module(模块),就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。

  文件名就是模块名加上后缀.py,在模块内部,模块名存储在全局变量__name__中,是一个string,可以直接在module中通过__name__引用到module name。

模块分为三种:

  • 自定义模块
  • 内置标准模块(又称标准库)
  • 开源模块

导入模块:

  • import: 使客户端(导入者)以一个整体获取一个模块。
  • from:容许客户端从一个模块文件中获取特定的变量名。
  • reload:在不中止Python程序的情况下,提供了一个重新载入模块文件代码的方法。
1
2
3
4
import module
from module.xx.xx import xx
from module.xx.xx import xx as rename 
from module.xx.xx import *

 模块路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#获取路径
import sys
for in sys.path:
    print(i)
#输出结果:
S:\Myproject
S:\Python 3.5.1\python35.zip
S:\Python 3.5.1\DLLs
S:\Python 3.5.1\lib                  #存放标准库
S:\Python 3.5.1
S:\Python 3.5.1\lib\site-packages    #存放第三方库,扩充库
 
#添加路径
import sys
import os
pre_path = os.path.abspath('../')
sys.path.append(pre_path)

开源模块:

#先安装 gcc 编译和 python 开发环境
yum install gcc
yum install python-devel
或
apt-get python-dev
 
#安装方式(安装成功后,模块会自动安装到 sys.path 中的某个目录中)
yum
pip
apt-get
...
#进入python环境,导入模块检查是否安装成功

time

   时间相关的操作,时间有三种表示方式:    

    •       时间戳               1970年1月1日之后的秒,即:time.time(),只有时间戳参数才能进行加减
    •         格式化的字符串    2014-11-11 11:11,    即:time.strftime('%Y-%m-%d')
    •         结构化时间          元组包含了:年、日、星期等... time.struct_time    即:time.localtime()
import time
print(time.time())                   #返回当前系统时间戳(1970年1月1日0时0分0秒开始)
print(time.ctime())                   #输出Tue May 17 16:07:11 2016,当前系统时间
print(time.ctime(time.time() - 86400))        #将时间戳转换为字符串格式
print(time.gmtime(time.time() - 86400))      #将时间戳转换为struct_time格式
print(time.localtime(time.time() - 86400))     #将时间戳转换为struct_time格式,返回本地时间
print(time.mktime(time.localtime()))         #与time.localtime()功能相反,将struct_time格式转回成时间戳格式
#time.sleep(5)                    #sleep停顿
print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()))  #将struct_time格式转成指定的字符串格式
print(time.strptime("2016-05-17","%Y-%m-%d"))   #将字符串格式转换成struct_time格式
 
 
print("----------------------------------------------------------------")
import datetime
print(datetime.date.today())             #输出格式 2016-05-17
print(datetime.date.fromtimestamp(time.time() - 86400)) #2016-05-16 将时间戳转成日期格式
current_time = datetime.datetime.now()
print(current_time)                 #输出2016-05-17 16:18:28.737561
print(current_time.timetuple())          #返回struct_time格式
print(current_time.replace(2008,8,8))         #输出2008-08-08 16:21:34.798203,返回当前时间,但指定的值将被替换
 
str_to_date = datetime.datetime.strptime("28/7/08 11:20","%d/%m/%y %H:%M")  #将字符串转换成日期格式
new_date = datetime.datetime.now() + datetime.timedelta(days=10)         #比现在加10天
new_date = datetime.datetime.now() + datetime.timedelta(days=-10)       #比现在减10天
new_date = datetime.datetime.now() + datetime.timedelta(hours=-10)       #比现在减10小时
new_date = datetime.datetime.now() + datetime.timedelta(seconds=120)      #比现在+120s
print(new_date)

random 模块

随机数:

import random
 
print(random.random())          #用于生成一个0到1的随机符点数: 0 <= n < 1.0
print(random.randint(1,2))      #用于生成一个指定范围内的整数
print(random.randrange(1,10))   #从指定范围内,按指定基数递增的集合中获取一个随机数
print(random.uniform(1,10))     #用于生成一个指定范围内的随机符点数
print(random.choice('nick'))    #从序列中获取一个随机元素
li = ['nick','jenny','car',]
random.shuffle(li)              #用于将一个列表中的元素打乱
print(li)
li_new = random.sample(li,2)    #从指定序列中随机获取指定长度的片断(从li中随机获取2个元素,作为一个片断返回)
print(li_new)

 

 生成随机验证码:

########## 随机验证码 1############
import random
temp = ''
for i in range(4):
    num = random.randrange(0,4)
    if num == 0 or num == 3:        #一半的概率
        rad2 = random.randrange(0,10)
        temp = temp + str(rad2)
    else:
        rad1 = random.randrange(65,91)
        c1 = chr(rad1)
        temp = temp + c1
print(temp)
########## 随机验证码 2############
 1 def v_code():  
 2     checkcode = "" # 定义一个空字符串
 3     for i in range(4): # 遍历四次
 4         num = random.randint(0,9) # 随机选择0到9的整形
 5         alf = chr(random.randint(65,90)) # 随机选择chr对应的字母
 6         add = random.choice([num,alf]) # 基于上面的可迭代对象选择一个
 7         checkcode += str(add) # 将它们变为字符串,加到空字符串里面
 8     return checkcode
 9 if __name__ == "__main__":
10     print(v_code())
 

 os模块

os模块用于提供系统级别的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd
os.curdir                   返回当前目录: ('.')
os.pardir                   获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2')    可生成多层递归目录
os.removedirs('dirname1')   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')         生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()                 删除一个文件
os.rename("oldname","new")  重命名文件/目录
os.stat('path/filename')    获取文件/目录信息
os.sep                      操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep                  当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep                  用于分割文件路径的字符串
os.name                     字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")   运行shell命令,直接显示
os.environ                  获取系统环境变量
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所指向的文件或者目录的最后修改时间

 sys模块

sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n)        退出程序,正常退出时exit(0)
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操作系统平台名称
sys.stdin          输入相关
sys.stdout         输出相关
sys.stderror       错误相关
# 手写进度条
import sys,time
for ii in range(101):
    sys.stdout.write('\r')  #每一次清空原行。
    sys.stdout.write("%s%%  |%s|"%(int(int(ii)/100*100),int(int(ii)/100*100) * '*'))     #一共次数除当前次数算进度
    sys.stdout.flush()      #强制刷新到屏幕
    time.sleep(0.05)
# 手写进度条

 json & picle 模块

用于序列化的两个模块

  • json,用于字符串 和 python数据类型间进行转换
  • pickle,用于python特有的类型 和 python的数据类型间进行转换

Json模块提供了四个功能:dumps、dump、loads、load

pickle模块提供了四个功能:dumps、dump、loads、load

  dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存 到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。

  dumps()函数执行和dump() 函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。

  loads()函数执行和load() 函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的str对象, 直接返回的对象。

 使用方法:

import json
# json的用法
dic = {"name":"alex"}
data = json.dumps(dic)
print(data)
print(type(data))
with open("hello","w") as f:
    f.write(data)


with open("hello","r") as new_f:
    i = new_f.read()
    a = json.loads(i)
    print(type(i))
    print(type(a))

{"name": "alex"}
<class 'str'>
<class 'str'>
<class 'dict'>

json
json
import pickle                # 和json的方法的相同,序列化对象
dic = {"name":"alex"}
# data = pickle.dumps(dic)   # 转化为字节类型
# print(data)                # ---><class 'bytes'>

f = open("hello","wb")
f.write(pickle.dumps(dic))   #
f.close()

f = open("hello","rb")      # 反序列化
data = pickle.loads(f.read())# 相当于data = pickle.load(f)
print(data)
f.close()

pickle
pikle

 

ickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

hashlib 模块

用于加密相关的操作,代替了md5模块和sha模块,主要提供md5(), sha1(), sha224(), sha256(), sha384(), and sha512()算法

 

import hashlib
 
# ######## md5 ########
 hash = hashlib.md5(bytes("bingdu",encoding="utf8")) # 创建md5对象,并额外加密
 hash.update(bytes("123",encoding="utf8")) # 对字符串加密
 print(hash.hexdigest()) # 取到密文

 

import hashlib
 
# ######## md5 ########
hash = hashlib.md5()
# help(hash.update)
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
print(hash.digest())
 
######## sha1 ########
 
hash = hashlib.sha1()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
 
# ######## sha256 ########
 
hash = hashlib.sha256()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
  
# ######## sha384 ########
 
hash = hashlib.sha384()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
 
# ######## sha512 ########
 
hash = hashlib.sha512()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
 
 
##### 加盐 ######
# ######## md5 ########
 
hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8"))
hash.update(bytes('admin',encoding="utf-8"))
print(hash.hexdigest())
 
#python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密
 
import hmac
 
h = hmac.new(bytes('898oaFs09f',encoding="utf-8"))
h.update(bytes('admin',encoding="utf-8"))
print(h.hexdigest())

 

shelve

shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型,会生成三个文件

import shelve
  
f = shelve.open(r'shelve.txt')
  
# f['stu1_info']={'name':'alex','age':'18'}
# f['stu2_info']={'name':'alvin','age':'20'}
# f['school_info']={'website':'oldboyedu.com','city':'beijing'}
#
#
# f.close()
  
print(f.get('stu_info')['age'])

 

Excel文件(xlrd,xlsxwriter)

复制代码
# -*- coding: utf-8 -*-
__author__ = 'suoning'

import xlrd

data = xlrd.open_workbook('F:\\message\\test.xlsx')

# 获取一个工作表
# table = data.sheets()[0]
# table = data.sheet_by_index(0)
table = data.sheet_by_name(u'Sheet1')

# 获取行数和列数
nrows = table.nrows
# nrows = table.ncols

# 使用行列索引
cell_A1 = table.row(0)[0].value
cell_A2 = table.col(1)[0].value
print cell_A1, cell_A2

# 单元格
cell_C1 = table.cell(0, 0).value
cell_C2 = table.cell(2, 1).value
print cell_C1, cell_C2

for i in range(nrows):
    print table.row_values(i)
    # # 获取整行和整列的值(数组)
    # table.row_values(i)
    # table.col_values(i)
# 写入

import xlsxwriter

# 建立文件
workbook = xlsxwriter.Workbook('F:\\message\\test.xlsx')
# 建立sheet, 可以work.add_worksheet('employee')来指定sheet名,但中文名会报UnicodeDecodeErro的错误
worksheet = workbook.add_worksheet()
# 向A1写入
worksheet.write('A1', 'Hello world')
worksheet.write('B1', '2017-02-13')

workbook.close()
复制代码

 

xml

跟json差不多,用作实现不同语言之间的数据交互,但是json使用起来更简单。

  至今很多传统和金融行业的系统的接口还是用的xml

  xml的格式如下,就是通过<>节点来区别数据结构的:

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>                                                  # 有一个xml的数据

 

接下来我们可以进行对它操作

import xml.etree.ElementTree as ET
tree = ET.parse("xml_t")  # 解析(打开)xml文件
root = tree.getroot() #
print(root.tag) # .tag是取第一层的标签
# 遍历root文档
for child in root:
    print(child.tag,child.attrib) # 取每条的标签名,还有每条标签的属性值(是字典)
    for i in child:
        print(i.tag,i.text) # 取子标签下的标签名,还有每条标签下的内容
# 只遍历yaer的节点
for node in root.iter("year"):
    print(node.tag,node.text) # 取出year的标签名,还有year标签名下的内容
#---------------------------------------
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.xml")
root = tree.getroot()
# 修改
for node in root.iter('year'):   # 只遍历yaer的节点
    new_year = int(node.text) + 1 # 将每个year标签下的内容整形并+1
    node.text = str(new_year)
    node.set("updated","yes")    # 添加。set(标签名,属性值)
tree.write("xmltest.xml")        # 写入新的修改的xml文件
# 删除
for country in root.findall('country'): # 遍历标签名为country下的东西
    rank = int(country.find('rank').text)# 找到country下的子标签为rank 取出它的内容,并复制
    if rank > 50: # 如果大于50
     root.remove(country) # 则删除country这个标签
 
tree.write('output.xml')

 

configarser

1 # 注释1
2 ;  注释2
3  
4 [section1] # 节点
5 k1 = v1    # 值
6 k2:v2       # 值
7  
8 [section2] # 节点
9 k1 = v1    # 值
View Code

 

例如有个简单的文件,如上我们可以对这个相应格式的文件进行一些操作

  1、获取所有节点 sections

1
2
3
4
5
6
import configparser
xx = configparser.ConfigParser()   # 创建一个对象
xx.read("ini",encoding="utf8")     # 读取相应文件
 
result = xx.sections()             # 获取所有节点
print(result)

  2、获取指定节点下所有的键 options

1
2
3
4
5
6
7
import configparser
xx = configparser.ConfigParser()  # 创建一个对象
# xx的对象的read功能,打开读取文件,放进内容
xx.read("ini",encoding="utf8")    # 读取相应文件
 
result = xx.options("kaixin")     # 获取指定节点下所有的键
print(result)

  3、获取指定节点下所有的键值对 items

1
2
3
4
5
6
7
import configparser
xx = configparser.ConfigParser()  # 创建一个对象
# xx的对象的read功能,打开读取文件,放进内容
xx.read("ini",encoding="utf8")    # 读取相应文件
 
result = xx.items("kaixin")       # 获取指定节点下的所有键值对
print(result)

  4、获取指定节点下指定key的值

1
2
result = xx.get("kaixin","age")
print(result)

  5、检查,添加,删除节点

1
2
3
4
5
6
7
8
9
10
11
# 检查节点是否存在,返回的是布尔值
has_sec = xx.has_section("kaixin")
print(has_sec)
 
# 添加节点
xx.add_section("Tom")
xx.write(open("ini","w"))
 
# 删除节点
xx.remove_section("Tom")
xx.write(open("ini","w"))

  6、检查、删除、设置指定组内的键值对

1
2
3
4
5
6
7
8
9
10
11
# 检查节点下的key值是否存在,返回的是布尔值
has_opt = xx.has_option("kaixin","age")
print(has_opt)
 
# 删除键值对
xx.remove_option("kaixin","money")
xx.write(open("ini","w"))
 
# 设置键值对
xx.set("tony","money","10000")
xx.write(open("ini","w"))

subprocess

 可以执行shell命令的相关模块和函数有

  • os.system
  • os.spawn*
  • os.popen*    —废弃
  • popen2.*  —废弃
  • commands.* —废弃,3.x中被移除

  以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能。

subprocess.Popen(...)

用于执行复杂的系统命令

参数:

  • args:shell命令,可以是字符串或者序列类型(如:list,元组)
  • bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
  • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
  • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
  • close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
  • 所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
  • shell:同上
  • cwd:用于设置子进程的当前目录
  • env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
  • universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
  • startupinfo与createionflags只在windows下有效
  • 将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等 
  • shell=True:  指定的命令行会通过shell来执行
  • stdin :   标准输入
  • stdout : 标准输出
  • stderr :  标准错误的文件句柄
  • PIPE :    管道 ,默认值 为: None, 表示不做重定向,管道可以用来接收数据。
1
2
3
4
5
6
7
把标准输出放入管道中,屏幕上就不会输出内容。
res=subprocess.Popen("dir", shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)   #执行dir命令,交给shell解释器执行,通过标准类型和subprocess.PIPE放入管道中。
 
>>> res.stdout.read()  #读取管道里面的数据,在程序中,读取也不会输出到屏幕上。
 
>>> res.stdout.read()   #再read一次,内容就为空,说明读取完成.
b''  #显示为:bytes类型

optparse

Python 有两个内建的模块用于处理命令行参数:

一个是 getopt,《Deep in python》一书中也有提到,只能简单处理 命令行参数;

另一个是 optparse,它功能强大,而且易于使用,可以方便地生成标准的、符合Unix/Posix 规范的命令行说明。

简单流程

首先必须导入模块optparse(这个不多说)
import optparse
# 创建OptionParser类对象
parser = optparse.OptionParser()
# 然后,使用add_option来定义命令行参数(伪代码)
# parser.add_option(opt_str, ...
#                   attr= value,...)
# 每个命令行参数就是由参数名字符串和参数属性组成的。如 -f 或者 –file 分别是长短参数名:
parser.add_option("-f","--file",dest = "filename")
# 最后,一旦你已经定义好了所有的命令行参数,调用 parse_args() 来解析程序的命令行:
options,args = parser.parse_args()

注: 你也可以传递一个命令行参数列表到 parse_args();否则,默认使用 sys.argv[:1]。
parse_args() 返回的两个值:
options,它是一个对象(optpars.Values),保存有命令行参数值。只要知道命令行参数名,如 file,就可以访问其对应的值: options.file 。
args,它是一个由 positional arguments 组成的列表。

 

struct

学习到socket网络编程这里,对struct有了认识,现在对它进行一些阐释,也可以较为有效的解决粘包问题

struct模块作用:解决bytes和其他二进制数据类型的转换

示例用法:
struct.pack('i',12)

参数说明:

pack函数作用:把任意数据类型变成bytes

i 表示4字节无符号整数。

import struct
struct.pack('i',12) # 用方法pack进行打包,把后面的整形数据,封装成一个bytes类型
b'\x0c\x00\x00\x00' # 长度就是4

l=struct.pack('i',12313123)
len(l)
4 #长度就是4

uppack

# 反解
struct.unpack('i',l)
(12313123,)

# 查看类型
l=struct.pack('i',1)
type(l)
<class 'bytes'>  # bytes类型

re

  正则表达式是用来匹配字符串非常强大的工具,在其他编程语言中同样有正则表达式的概念。就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执

 re模块提供了正则表达式的相关操作

  是直接面向字符串的模糊匹配

  元字符包含有 . ^ $ * + ? {} [] | () \

   介绍字符

    .  通配符,除了换行符之外的任意字符

    ^   匹配字符串的开始

    $  匹配字符串的结尾

   关于次数的

    *  按紧挨着的字符重复无数次  重复零次或更多次    

    +  1到无穷次  重复一次或更多次

    ?  (0,1)  重复零次或一次

    {n}   重复n次
    {n,}  重复n次或更多次
    {n,m}重复n到m次

 

#导入 re 模块
import re
 
= 'nick jenny nice'
 
# 匹配方式(一)
= re.match(r'nick',s)
= b.group()
print(q)
 
# 匹配方式(二)
# 生成Pattern对象实例,r表示匹配源字符串
= re.compile(r'nick')
print(type(a))               #<class '_sre.SRE_Pattern'>
 
= a.match(s)
print(b)                     #<_sre.SRE_Match object; span=(0, 4), match='nick'>
 
= b.group()
print(q)
 
 
#被匹配的字符串放在string中
print(b.string)              #nick jenny nice
#要匹配的字符串放在re中
print(b.re)                  #re.compile('nick')

  两种匹配方式区别在于:第一种简写是每次匹配的时候都要进行一次匹配公式的编译,第二种方式是提前对要匹配的格式进行了编译(对匹配公式进行解析),这样再去匹配的      时候就不用在编译匹配的格式。

匹配规则:

  .
  "." 匹配任意字符(除了\n)
  \
  "\" 转义字符
  [...]
  "[...]" 匹配字符集

 

<br># "." 匹配任意字符(除了\n)
a = re.match(r".","95nick")
b = a.group()
print(b)
 
# [...] 匹配字符集
a = re.match(r"[a-zA-Z0-9]","123Nick")
b = a.group()
print(b)
  \d   
  匹配任何十进制数;它相当于类 [0-9]
  \D 
  匹配任何非数字字符;它相当于类 [^0-9]
  \s
  匹配任何空白字符;它相当于类 [\t\n\r\f\v]
  \S
  匹配任何非空白字符;它相当于类 [^\t\n\r\f\v]
  \w
  匹配任何字母数字字符;它相当于类 [a-zA-Z0-9]
  \W  
  匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9]
  *
   "*" 匹配前一个字符0次或者无限次
  +
   "+" 匹配前一个字符1次或者无限次
  ?
    "?" 匹配一个字符0次或者1次

   {m} {m,n}

    {m} {m,n} 匹配前一个字符m次或者m到n次

   *? +? ??

    *? +? ?? 匹配模式变为非贪婪(尽可能少匹配字符串)
   ^  
   "^" 匹配字符串开头,多行模式中匹配每一行的开头
   $
   "$" 匹配字符串结尾,多行模式中匹配每一行的末尾
   \A
   \A 仅匹配字符串开头
    \Z

   \Z 仅匹配字符串结尾

    \b

   \b 匹配一个单词边界,也就是指单词和空格间的位置
  |
  "|" 匹配左右任意一个表达式
  ab
  (ab) 括号中表达式作为一个分组
  \<number>
  \<number> 引用编号为num的分组匹配到的字符串
  (?P<key>vlaue)
  (?P<key>vlaue) 匹配到一个字典,去vlaue也可做别名
  (?P=name)
  (?P=name) 引用别名为name的分组匹配字符串

 模块方法介绍:

  match

   从头匹配

  search

  匹配整个字符串,直到找到一个匹配


  findall

  找到匹配,返回所有匹配部分的列表

   finditer

  返回一个迭代器

  sub

  将字符串中匹配正则表达式的部分替换为其他值

  split

  根据匹配分割字符串,返回分割字符串组成的列表
  group()
  返回被 RE 匹配的字符串
  groups()
 
  返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号
  groupdict()
 
  返回(?P<key>vlace)定义的字典
  start()
  返回匹配开始的位置
  end()
  返回匹配结束的位置
  span()
  返回一个元组包含匹配 (开始,结束) 的索引位置
  re.I
  使匹配对大小写不敏感
  re.L
  做本地化识别(locale-aware)匹配
  re.M
  多行匹配,影响 ^ 和 $
  re.S  
  使 . 匹配包括换行在内的所有字符
  re.U
  根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
  re.X
 
  注释,会影响空格(无效了)

re下面的方法

  常用的功能函数包括:compile、search、match、split、findall(finditer)、sub(subn)

    comoile

1
2
3
obj=re.compile('\d{5}')       # compile是编译的意思,编译好一个规则,再进行调用它
ret=obj.search('abc12345ee')
print(ret.group())#12345

    serch

1
2
3
4
print(re.search('al','alvin yuan').group()) # al
 
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

    findall

1
2
3
print(re.findall('a','alvin yuan'))# ['a', 'a']
 
# 返回所有满足匹配条件的结果,放在列表里

    match

1
2
ret = re.match('a','abc').group() # match只是从开始匹配,匹配成功则返回对象
print(ret)

    split

1
2
ret=re.split('[ab]','abcd')     # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)#['', '', 'cd']       # 结果放在列表中

    sub(subn)

1
2
3
4
ret=re.sub('\d','abc','alvin5yuan6',1)   # sub里面至少有个三个参数 依次是 匹配规则 替换内容 源数据     也可以有四个,最后一个参数是匹配次数
print(ret)#alvinabcyuan6
ret=re.subn('\d','abc','alvin5yuan6')    # 显示匹配了多少次,替换
print(ret)#('alvinabcyuanabc', 2)

    finditer

1
2
3
4
5
6
ret=re.finditer('\d','ds3sy4784a')
print(ret)        #<callable_iterator object at 0x10195f940>
print(next(ret).group())
print(next(ret).group())
 
# 结合迭代器规则,返回的是一个迭代器对象,应用于处理很多的数据,用next的可以逐一取

  ?:  是取消优先级         ?P的含义

1
2
print(re.search("(?P<name>[a-z]+)(?P<age>\d+)","alex36wusir27").group("name"))
# alex 注释 ?P是定义死的 <定义分组名>                                 后面可根据分组名取值
1
2
3
4
print(re.findall("www\.(baidu|taobao)\.com","sdaswww.baidu.comsdf"))
# ['baidu'] 优先给分组的内容,其实已经匹配到了
print(re.findall("www\.(?:baidu|taobao)\.com","sdaswww.baidu.comsdf"))
# ['www.baidu.com']    ?: 表示去掉括号内的优先级

logging

  用于便捷记录日志且线程安全的模块

  日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,当然也可以自己定义日志级别。

  level=logging.DEBUG 设置日志级别

1
2
3
4
5
6
7
8
9
10
11
12
13
import logging
 
logging.basicConfig(filename='log.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=logging.DEBUG)
 
logging.debug('debug')            # 分五个等级
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')

文件输出如下

format 设置输出格式

     %(levelno)s: 打印日志级别的数值
     %(levelname)s: 打印日志级别名称
     %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
     %(filename)s: 打印当前执行程序名
     %(funcName)s: 打印日志的当前函数
     %(lineno)d: 打印日志的当前行号
     %(asctime)s: 打印日志的时间
     %(thread)d: 打印线程ID
     %(threadName)s: 打印线程名称
     %(process)d: 打印进程ID
     %(message)s: 打印日志信息

datefmt 设置日期格式,同 time.strftime()

      %Y 年 %m 月  %D日  %H时  %M分  %S 秒

filename 设置文件路径

filemode 设置文件打开模式 

注:没有filename和filemode直接输出

 

上图所示,是得到

  os.path.dirname是返回上一级目录

  关于os模块的补充  

os.walk(top, topdown=True, onerror=None, followlinks=False) 
可以得到一个三元tupple(dirpath, dirnames, filenames), 
第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。
dirpath 是一个string,代表目录的路径,
dirnames 是一个list,包含了dirpath下所有子目录的名字。
filenames 是一个list,包含了非目录文件的名字。
这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath, name).
通过for循环自动完成递归枚举

# 做个简单的例子,输出crm目录的下所有文件的路径信息
for a,b,c in os.walk(str(PATH) + os.sep + "crm" ):
    for item in c:
        # print(item)
        print(os.path.join(a,item))

输出
F:\python\crm\.idea\.name
F:\python\crm\.idea\crm.iml
F:\python\crm\.idea\encodings.xml
F:\python\crm\.idea\misc.xml
F:\python\crm\.idea\modules.xml
F:\python\crm\.idea\workspace.xml
F:\python\crm\bin\bin.py
F:\python\crm\bin\__init__.py
F:\python\crm\bin\__pycache__\bin.cpython-35.pyc
F:\python\crm\core\admin.py
F:\python\crm\core\coures.py
F:\python\crm\core\grade.py
F:\python\crm\core\school.py
F:\python\crm\core\student.py
F:\python\crm\core\teacher.py
F:\python\crm\core\__init__.py
F:\python\crm\core\__pycache__\admin.cpython-35.pyc
F:\python\crm\core\__pycache__\coures.cpython-35.pyc
F:\python\crm\core\__pycache__\grade.cpython-35.pyc
F:\python\crm\core\__pycache__\school.cpython-35.pyc
F:\python\crm\core\__pycache__\student.cpython-35.pyc
F:\python\crm\core\__pycache__\teacher.cpython-35.pyc
F:\python\crm\core\__pycache__\__init__.cpython-35.pyc
F:\python\crm\db\admin\alex
F:\python\crm\db\coures\23eeeb4347bdd26bfc6b7ee9a3b755dd
F:\python\crm\db\coures\34d1f91fb2e514b8576fab1a75a89a6b
F:\python\crm\db\coures\c71e8d17d41c21de0d260881d69662ff
F:\python\crm\db\coures\df5fb5e33c5585bb0c48107c57cece9b
F:\python\crm\db\coures\e206a54e97690cce50cc872dd70ee896
F:\python\crm\db\grade\270c42ba7614f1a475f61dfcb397a621
F:\python\crm\db\grade\817ee0b8010393ff3b4483e703663551
F:\python\crm\db\school\17811d3caeff9648f48b5a553c806c63
F:\python\crm\db\school\b035c88ee6f5270ccff67a591d0e21ec
F:\python\crm\db\school\bb0ac3d8eb8f2c2f6fe336c5e9957392
F:\python\crm\db\school\e523d5f211747bdfc742f50463577f74
F:\python\crm\db\student\6e7e12c264fb3e1f456b0782f47e4af6
F:\python\crm\db\student\a0b5e2d3a97d7a19ec6d2da830f609b2
F:\python\crm\db\student\a995b03ed63f8c7128a83c984b89aa50
F:\python\crm\db\student\fe01b2ba5ec0146e5d4b0885822556ef
F:\python\crm\db\student\ff4916088e836d268a9d72f8929bac06
F:\python\crm\db\teacher\08319d4fed47c8ed828ebabd5a91563b
F:\python\crm\db\teacher\0d1d5cd3623144f692fb771580b92288
F:\python\crm\db\teacher\5d00d0762936aedda519d63c2e4a2a40
F:\python\crm\db\teacher\6a7ece82e4ed94a475dab275891d5036
F:\python\crm\lib\ceshi.py
F:\python\crm\lib\readme
F:\python\crm\lib\readwrite.py
F:\python\crm\lib\__init__.py
F:\python\crm\lib\__pycache__\readwrite.cpython-35.pyc
F:\python\crm\lib\__pycache__\__init__.cpython-35.pyc

用os.walk 遍历目录
import os

res = os.path.getsize(os.path.join("F:\python\PycharmProjects\date2017.1.8","path_search.py"))
print(res)

ret  = os.stat(os.path.join("F:\python\PycharmProjects\date2017.1.8","path_search.py")).st_size
print(ret)

f = open(os.path.join("F:\python\PycharmProjects\date2017.1.8","path_search.py"),"rb")
print(len(f.read()))

输出结果相同

获取文件大小的三种方式
posted @ 2017-05-29 23:37  红领巾下的大刀疤  阅读(162)  评论(0编辑  收藏  举报
/* 看板娘 */