目录

  一、基础概念

    1、模块定义

    2、包的定义

    3、导入包的本质

    4、导入模块的本质

    5、导入方法

    6、import的本质

    7、导入优化

    8、模块分类

    9、标准库介绍

      1、time与datetime

      2、random模块

      3、os模块

      4、sys模块

      5、shutil模块

      6、shelve模块

      7、XML模块

      8、Pyyaml模块

      9、configParser模块

      10、hashlib模块

      11、re模块

      12、collections模块

      13、subprocess模块

      14、logging模块

    10、二分法

    11、冒泡排序

    12、时间复杂度

    13、深拷贝

一、基础概念:

  1、模块定义

  本质就是.py结尾的python文件(文件名:test.py 对应模块名: test),用来从逻辑上组织python代码(变量、函数、类、逻辑)

  2、包的定义

  用来从逻辑上组织模块的,本质就是一个目录(必须带有一个名字叫__init__.py的文件)

  3、导入包的本质

  执行包目录下所在的__init__.py文件

  4、导入模块的本质

  将该模块的python文件在导入的程序中通过解释器去解释一遍

  5、导入方法

    1、import module_name

    2、import module_name1,module_name2.....

    3、from module_name import func_name (as   func1_name)  #可以对导入的函数起别名,为了避免与本文件的函数重名导致功能没法实现

  6、import的本质

  导入模块本质就是找到这个文件,并且把python文件解释一遍,其中import test 表示    test=‘test.py   all code’  把该test.py文件全部解释一遍,而from test import m m=‘test.py about m code’  表示从test.py文件中取出关于m的代码在本文件中解释一遍

  7、导入优化

  通常情况下,使用import module_name 如果在其中总是使用test函数,这样每次在使用时会实现检查test函数在module_name模块中是否存在,为了提高效率,可以使用from module_name import test方法导入该函数,相当于直接将test函数在这里直接解释了一编,提高运行效率

  8、模块分类

    1、标准库也叫内置模块

    2、开源模块也叫第三方模块

    3、自定义模块

  9、标准库介绍

    1、time与datetime

时间戳,以秒为单位

      time.time()函数,以秒来计算

print(time.time())  #time.time不需要提供任何参数,表示自1970年1月1日到现在经过多少秒
#输出:
1487733672.621412

  

      元组方式表示时间struct_time,包括了9个元素

      time.localtime()#如果里面没有提供任何参数,会表示当前时间, 如果里面提供已秒为单位的数字,会显示对应其对应时间

print(time.localtime())
#输出
time.struct_time(tm_year=2017, tm_mon=2, tm_mday=22, tm_hour=14, tm_min=34, tm_sec=7, tm_wday=2, tm_yday=53, tm_isdst=0)#其中wday代表本周第几天,yday代表本年的第几天,而lsdst代表夏令时
#DST:夏令时
#UTC:世界标准时间

      time.timezone #以秒的格式表示时区

print(time.timezone)
#输出
-28800 #28800/3600=8表示东八区

      time.daylight#是否使用夏令时

print(time.daylight)
#输出
0

      time.sleep()#其中跟参数表示暂停运行几秒

time.sleep(3)

      time.gmtime与locatime

      两者都是表示以元组形式表示时间,同时都以秒为所传参数,其中gmtime表示UTC时间,而localtime表示本地时间

print(time.gmtime())
print(time.gmtime(394049430))
#输出
time.struct_time(tm_year=2017, tm_mon=2, tm_mday=22, tm_hour=6, tm_min=53, tm_sec=56, tm_wday=2, tm_yday=53, tm_isdst=0)
time.struct_time(tm_year=1982, tm_mon=6, tm_mday=27, tm_hour=18, tm_min=10, tm_sec=30, tm_wday=6, tm_yday=178, tm_isdst=0)
print(time.localtime())
print(time.localtime(394049430))
#输出
time.struct_time(tm_year=2017, tm_mon=2, tm_mday=22, tm_hour=14, tm_min=54, tm_sec=57, tm_wday=2, tm_yday=53, tm_isdst=0)
time.struct_time(tm_year=1982, tm_mon=6, tm_mday=28, tm_hour=2, tm_min=10, tm_sec=30, tm_wday=0, tm_yday=179, tm_isdst=0)
x = time.localtime()
print(x.tm_year) #同理,在得到的strcut_time中可以根据参数取不同的值
#输出
2017

      time.mktime()#直接传入元组的形式,变为对应的秒

x = time.localtime(394049430)
print(x)
print(time.mktime(x)) #通过传入已元组形式的时间,转换成对应的秒
#输出
time.struct_time(tm_year=1982, tm_mon=6, tm_mday=28, tm_hour=2, tm_min=10, tm_sec=30, tm_wday=0, tm_yday=179, tm_isdst=0)
394049430.0

  

      time.strftime()#将struct_time转成格式化的时间字符串

x = time.localtime(394049430)
print(time.strftime('%Y-%m-%d %H:%M:%S', x))#%Y代表四位的年,%y代表两位表示的年,%m代表月,%M代表分钟,%H代表小时,%S代表秒 %w代表这种的第几天
#输出
1982-06-28 02:10:30

      time.strptime()#将格式化的时间字符串转成struct_time

x = time.localtime(394049430)
y = time.strftime('%y-%m-%d %H:%M:%S', x)
print(time.strptime(y,'%%m-%d %H:%M:%S'))# 前面为格式化的时间字符串,后面是对应的格式,可以将该格式化时间字符串变为struct_time元组,格式只要匹配就可以,没有顺序要求例如:time.strptime("02-20 14:08:34 2017", "%m-%d %H:%M:%S %Y")
#输出
time.struct_time(tm_year=1982, tm_mon=6, tm_mday=28, tm_hour=2, tm_min=10, tm_sec=30, tm_wday=0, tm_yday=179, tm_isdst=-1)

      strftime('格式',struct_time(元组格式))  --->转换成格式化时间字符串

      strptime('格式化时间字符串',‘格式’)  -----> 转成成struct_time

      转换关系:

        时间戳转成struct_time:gmtime、localtime

        struct_time转成时间戳:mktime

        struct_time转成格式化时间字符串:strftime

        格式化时间字符串转成struct_time:strptime

      time.asctime()#将struct_time转成格式化时间字符串,格式为%a %b %d  %H:%M:%S %Y,其中%a表示星期,%b表示月,如果asctime没有传递参数,默认会导入localtime()的结果

print(time.asctime())
x = time.localtime(394049430)
print(time.asctime(x))
#输出
Wed Feb 22 15:44:21 2017
Mon Jun 28 02:10:30 1982

      time.ctime()将时间戳转成为%a %b %d  %H:%M:%S %Y,其中%a表示星期,%b表示月

print(time.ctime()) #如果没参数传递,会将locatime转成成的秒传进去
x = time.time()
print(time.ctime(x)) #传递进来的是时间戳,为秒
#输出
Wed Feb 22 15:48:25 2017
Wed Feb 22 15:48:25 2017

      datetime模块:

        datetime.datetime.now()#获取当前时间

print(datetime.datetime.now())
#输出
2017-02-22 15:52:24.551932

        datetime.datetime.now()+datetime.timedelta(3) #默认是三天后的时间

print(datetime.datetime.now()+datetime.timedelta(3))
#输出
2017-02-25 15:54:03.199349

        datetime.datetime.now()+datetime.timedelta(-3)#三天前的时间

print(datetime.datetime.now()+datetime.timedelta(-3))
#输出
2017-02-19 15:54:59.262861

        datetime.datetime.now()+datetime.timedelta(hours=3)#三小时后的时间

print(datetime.datetime.now()+datetime.timedelta(hours=3))
#输出
2017-02-22 19:04:30.683096

        datetime.datetime.now()+datetime.timedelta(hours=-3)#三小时前的时间

print(datetime.datetime.now()+datetime.timedelta(hours=-3))
#输出
2017-02-22 13:05:11.410832

        当前时间替换time.replace()

c_time= datetime.datetime.now()
print(c_time) r_time = c_time.replace(minute=3,hour=2)
print(r_time)
#输出
2017-02-22 16:08:55.694556
2017-02-22 02:03:55.694556

  

    2、random模块

import random

print(random.random())  #random()函数会在0-1之间随机取值
#输出
0.28605143730067417 print(random.randint(1,3)) #从整数中随机取值,得到的值均为1-3之间,1和3均有机会取到
#输出
3 print(random.randrange(1,3))#随机取1-2的整数,不会取到3
#输出
2 print(random.choice('abcde')) #choice表示从序列中取值,序列包括字符串 元组 列表 字典
#输出
#b
print(random.choice([4,3,2,4]))
#输出
3
print(random.choice((4,3,2,4)))
#输出
4 print(random.sample('hello word',4)) #随机取四个数字
#输出
#['r', 'l', 'w', 'h'] print(random.uniform(1,3)) #手工设置random.random的取值范围,默认只是0-1之间,通过uniform方法可以做到在任意范围
#输出
2.07789196870395 item = [1,2,3,4,5,6,7,8]
random.shuffle(item)
print(item)
#输出
[5, 2, 3, 8, 6, 4, 1, 7]

    例子:

      验证码

import  random

checkcode = ''

for i in range(1,6):
x = random.randint(0,9) #取0-9随机数
if x == i:
x = chr(random.randint(65,90)) #将随机取一个数字然后转换成ascii码
else:
x = random.randint(0,9)
checkcode += str(x) #添加x到字符串中
print(checkcode)

    3、os模块

>>> import os
>>> os.getcwd() #获取当前路径
'/Users/Gavin'
>>> os.chdir('/Users') #修改当前路径
>>> os.getcwd()
'/Users'
>>> os.curdir #获取当前目录
'.'
>>> os.pardir #获取上一级目录
'..'
>>> os.makedirs('/Users/Gavin/Desktop/a/b/c') #创建目录,就算没有父级目录页会递归创建
>>> os.removedirs('/Users/Gavin/Desktop/a/b/c')#删除目录,如果父集目录没有文件也会随之删除
os.mkdir('/Users/Gavin/Desktop/a/b/c')#如果创建的目录中没有父集目录会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/Users/Gavin/Desktop/a/b/c'
>>>os.mkdir('/Users/Gavin/Desktop/a')
>>>os.rmdir('/Users/Gavin/Desktop/a')#删除创建的目录
>>>os.listdir('/Users/Gavin/Desktop')#列出目录中的文件以及子目录
>>>os.remove('/Users/Gavin/Desktop/ä¸两ç½网å合å¹并.xlsx')#删除对应的文件
>>>os.rename('/Users/Gavin/Desktop/oldname.doc','/Users/Gavin/Desktop/newname.doc')#修改文件名
>>>os.stat('/Users/Gavin/Desktop/newname.doc')
os.stat_result(st_mode=33152, st_ino=40047776, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=116224, st_atime=1487753837, st_mtime=1487753837, st_ctime=1487753837)
>>> os.sep #显示特定系统的目录分隔符
'/'
>>> os.linesep #显示特定系统的换行符
'\n'
>>> os.pathsep#显示特定系统的路径分隔符
':'
os.environ #显示环境变量
environ({'SHELL': '/bin/bash', 'SHLVL': '', 'PWD': '/Users/Gavin', 'TMPDIR'})
>>> os.name
'posix'
os.system('ls -l') #执行系统bash命令
total 2992
drwx------ 3 Gavin staff 102 10 29 11:42 Applications
drwx------+ 35 Gavin staff 1190 2 22 22:10 Desktop
>>> os.path.abspath('__file__') #查找文件的绝对路径
'/Users/Gavin/__file__'
>>> os.path.split('/Users/Gavin') #os.path.split会将字符串通过/分割为两部分,不管文件或者路径是否存在
('/Users', 'Gavin')
>>> os.path.split('a/b')
('a', 'b')
>>> os.path.dirname(os.path.abspath('__file__')) #os.path.dirname显示文件所在路径
'/Users/Gavin'
>>> os.path.basename(os.path.abspath('__file__')) #os.path.basename只显示文件名
'__file__'
>>> os.path.exists('/Users/Gavin') #os.path.exists判断文件或者目录是否存在
True
>>> os.path.exists('/Users/a')
False
>>> os.path.isfile('/Users/Gavin/Desktop/newname.doc') #判断是否为文件
True
>>> os.path.isfile('/Users/Gavin/Desktop/oldboy')
False
>>> os.path.isfile('/Users/Gavin/Desktop/oa') #就算不存在也不会报错只不过显示不为文件
False
>>> os.path.isdir('/Users/Gavin/Desktop/oa') #判断目录是否为目录,不存在也不会报错
False
>>> os.path.isdir('/Users/Gavin/Desktop') #判断是否为目录
True
>>> os.path.join('a','b') #将前面两个字符串通过/方式合并
'a/b'
>>> os.path.join('/Users','Gavin')
'/Users/Gavin'
>>> os.path.getatime('/Users/Gavin') #目录或者文件的访问时间
1487772945.0
>>> os.path.getctime('/Users/Gavin') #目录或者文件的创建时间
1486950756.0

    4、sys模块

>>> sys.version  #显示python版本号
'3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) \n[GCC 4 vim sys-test.py
import sys
print(sys.argv[1])
print(sys.argv[2])
>>>python3 sys-test.py a b
a
b
>>>sys.exit(1) #退出,默认情况下正常退出为0

    5、shutil模块

      进行高级的文件、文件夹的拷贝工作,还可以压缩包

      shutil.copyfileobj(src_file,dest_file) #拷贝文件,不常用,因为没有流控制

import shutil

source_file= open('本节笔记','r',encoding='utf-8')
dest_file = open('本节拷贝','w',encoding='utf-8')
shutil.copyfileobj(source_file,dest_file)

      shutil.copyfile(src_file,dest_file)#拷贝文件,copyfile比copyfileobj多了with open file as f这个步骤,所以无需使用source_file  和dest_file这两个变量代替引用

shutil.copyfile('本节笔记','本节拷贝')   #源文件存在,目标文件可以存在,也可以不存在

      shutil.copymode(src_file,dest_file) #只拷贝权限,内容,组、用户都不变

shutil.copymode('本节笔记','本节拷贝')  #目标文件需要存在,只拷贝权限

      shutil.copystat(src_file,dest_file)#拷贝状态的信息,包括:mode bits, atime, mtime, flags

shutil.copymode('本节笔记','本节拷贝')  #目标文件需要存在,只拷贝权限

      shutil.copy(src_file,dest)#copy比copyfile更高明的一点就是在于dest就算是目录,copy动作也会成功,同时会在dest的目录下创建一个和src_file完全相同的文件名,比copyfile多了copymode方法

shutil.copy('本节笔记','/Users/Gavin/PycharmProjects/python/day5/test')

      shutil.copy2(src_file,dest)#copy2和copy类似,和copy的区别在于不是调用copymode,而是调用copystat函数

shutil.copy2('本节笔记','/Users/Gavin/PycharmProjects/python/day5')

      shutil.copytree('src_dict','dest_dict') #copytree是目录拷贝,将源目录所有文件和目录全部拷贝到目标目录,有个必须注意的地方在于dest_dict目录必须是不存在的,如果存在就会报错

shutil.copytree('/Users/Gavin/Desktop/a','/Users/Gavin/Desktop/k')

      shutil.rmtree('目录')#rmtree会递归方式删除相应目录

shutil.rmtree('/Users/Gavin/Desktop/a')

      shutil.move(src_dict,dest_dict)#将a目录更名为b目录,如果在不同路径下,就完成移动动作

shutil.move('/Users/Gavin/Desktop/a','/Users/Gavin/Desktop/b')

      shutil.make_archive(base_name,format,root=dir='')

shutil.make_archive('/Users/Gavin/Desktop/b/desktop','zip',root_dir='/Users/Gavin/Desktop/b')
'''第一个参数表示base_name即压缩后的名字,后缀名会自动添加为第二个参数也就是压缩的方法包括:bztar,gztar,tar,xztar,zip等方法可选,root_dir表要压缩
目录或者文件,总体来讲,第一个是压缩后的basename,如果第一个参数只写了名字而没有写目录,会将压缩包保存到当前目录然后添加后面第二个参数为扩展名,第三个参数表示要压缩的目录或者文件'''
print(shutil.get_archive_formats()) #表示压缩打包包括哪几种方法,如果忘记可以通过该函数进行查询

      补充说明:

      shutil对压缩包的调用ZipFile和TarFile两个模块完成的

        a) ZipFile函数

import zipfile
#压缩
z = zipfile.ZipFile('压缩名.zip','w') #压缩文件
z.write('本节笔记') #要压缩的文件添加
z.write('本节拷贝') #要压缩的文件添加
z.close()
#解压
z = zipfile.ZipFile('压缩名.zip','r')
z.extractall() #将压缩文件解压
z.close()

        b) TarFile

import tarfile
#打包
tar = tarfile.open('tar.tar','w')
tar.add('本节笔记.zip',arcname='本节笔记.zip')
#tar.add('本节拷贝',arcname='本节拷贝.zip')
tar.close()
#解包
tar = tarfile.open('tar.tar','r')
tar.extractall()
tar.close()

    6、shelve模块

      一个简单的k,v 将内存数据通过持久化的模块,可以持久任何pickle可支持python数据格式

import shelve,datetime

info = {'name':'gavin', 'age': 16 ,'job': 'IT'}
name1 = [1,2,3,4,5]
name2 = 'abededg'
time_now = datetime.datetime.now()
#持久化存储
with shelve.open('shelve_test',) as f: #通过shelve.open方式打开文件,不需要写w和r
f['info'] = info #将需要持久化的数据导入shelve_test中保存
f['name1'] = name1
f['name2'] = name2
f['time_now'] = time_now #从文件中读取
with shelve.open('shelve_test',) as f:
print(f.get('name1')) #通过k方式获取value
print(f.get('info'))
print(f.get('name2'))
print(f.get('time_now'))

    7、XML模块

      xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

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

<?xml version="1.0"?>
<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协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml

import xml.etree.ElementTree as ET

tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag) #遍历xml文档
for child in root:
print(child.tag, child.attrib)
for i in child:
print(i.tag,i.text) #只遍历year 节点
for node in root.iter('year'):
print(node.tag,node.text)

      修改和删除xml文档内容

import xml.etree.ElementTree as ET

tree = ET.parse("xmltest.xml")
root = tree.getroot() #修改
for node in root.iter('year'):
new_year = int(node.text) + 1
node.text = str(new_year)
node.set("updated","yes") tree.write("xmltest.xml") #删除node
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country) tree.write('output.xml')

      自己创建xml文档

import xml.etree.ElementTree as ET

new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
age = ET.SubElement(name,"age",attrib={"checked":"no"})
sex = ET.SubElement(name,"sex")
sex.text = ''
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
age = ET.SubElement(name2,"age")
age.text = '' et = ET.ElementTree(new_xml) #生成文档对象
et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式

    8、Pyyaml模块

      Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation

    9、configParser模块

      用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser。

       a)生成config文件

import configparser

config = configparser.ConfigParser()

config['DEFAULT'] = {
'ServerAliveInterval': '',
'Compresssion': 'yes',
'CompressionLevel': ''
} config['bitbucket.org'] = {}
bitbucket = config['bitbucket.org']
bitbucket['User'] = 'hg'
config['topsercret.server.com'] = {}
topsercert = config['topsercret.server.com']
topsercert['Host Port'] = ''
topsercert['ForwardX11'] = 'no'
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as f:
config.write(f)
#输出
[DEFAULT]
serveraliveinterval = 45
compressionlevel = 9
compresssion = yes
forwardx11 = yes [bitbucket.org]
user = hg [topsercret.server.com]
host port = 50022
forwardx11 = no

      b)读配置文件

import configparser

config = configparser.ConfigParser()

print(config.sections()) #开始没有读进来之前没法看到sections

config.read('example.ini')

print(config.sections())  #通过sections函数没法读到default内容

conf_default = config.defaults()
for line in conf_default:
print('%s:\t%s' %(line,conf_default[line])) print(config['bitbucket.org']['User']) if 'bitbucket.org' in config:
print(True) topsecert = config['topsercret.server.com']
print(topsecert['Host Port'])
for key in config['bitbucket.org']:
print(key)
#输出
[]
['bitbucket.org', 'topsercret.server.com']
serveraliveinterval: 45
compressionlevel: 9
compresssion: yes
forwardx11: yes
hg
True
50022
user
serveraliveinterval
compressionlevel
compresssion
forwardx11

      c)修改配置文件

import configparser

config = configparser.ConfigParser()

config.read('example.ini')

#读取
secs = config.sections()
print(secs) options = config.options('bitbucket.org') #单独针对调用某一section对应的配置选项,options选项会将default选项内容带入
print(options) item_list= config.items('bitbucket.org') #针对调用section中对应的配置选项已经对应参数,item选项会将default选项也带入
print(item_list) val = config.get('bitbucket.org','user')
print(val)
val = config.get('bitbucket.org','compresssion')
print(val) #修改
sec = config.remove_section('bitbucket.org') #移除secion
sec = config.add_section('DB') #添加section
sec = config.has_section('DB') #判断section是否存在
print(sec)
sec = config.has_option('topsercret.server.com','forwardx11') #判断section中的option是否存在
print(sec) config.set('DB','mysql','https://www.mysql.com/3306') #对section中的option添加参数,必须为str类型 config.remove_option('topsercret.server.com','Host Port') #移除section内option
with open('example1.ini','w') as f:
config.write(f)
#输出
[DEFAULT]
serveraliveinterval = 45
compressionlevel = 9
compresssion = yes
forwardx11 = yes [topsercret.server.com]
forwardx11 = no [DB]
mysql = https://www.mysql.com/3306

    10、hashlib模块

      用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

import hashlib

m = hashlib.sha512()  #hashlib还包括md5 sha1等不同安全等级的函数调用

m.update('hello'.encode(encoding='utf-8'))

print(m.hexdigest())  #按照16进制格式显示

m.update('中文也可以加密'.encode(encoding='utf-8'))
print(m.hexdigest()) m1 = hashlib.sha512()
m1.update('hello中文也可以加密'.encode(encoding='utf-8'))
print(m1.hexdigest()) m2 = hashlib.sha512()
with open('config.cfg','r') as f:
f1 = f.read() m2.update('f1'.encode(encoding='utf-8')) #可以将整个文件进行加密
print(m2.hexdigest())
#输出
9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
9600f16b6ac743e6a78557de89b458f9c373424d8762ed4730397148e5f352d0339e879786fd0404635c907503f7a73ae70ea9be82dbcf9a1c66cc77f33690de
9600f16b6ac743e6a78557de89b458f9c373424d8762ed4730397148e5f352d0339e879786fd0404635c907503f7a73ae70ea9be82dbcf9a1c66cc77f33690de
bc07fac547256ebcf7abc70731753f4ba70d4c09d856fab4f89255787bde9cbadc2ab85a77dcbbb523a7acf818bdf8db2da5ffb9b1a4d2b4ad71810795d3a546

      python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密

import hmac

h = hmac.new('中文key也可以'.encode(encoding='utf-8'),'message也是可以是中文'.encode(encoding='utf-8')) #前面是key,后面mess,在后面可以使用加密方法,但是一直没有使用过
h.update('我们在奋斗的路上一直不停留'.encode(encoding='utf-8'))
print(h.hexdigest())
#输出
749c771880c1cf952c957623605918d8

    11、re模块

      常用的正则表达式符号

        '.'  默认匹配除了\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行

        ’^‘  匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r'^a', '\nabc\necc',flags=re.MULTILINE)

        '$'  匹配字符结尾,或e.search('foo$', 'bfoo\nsdfsf', flags=re.MULTILINE).group()也可以

        ’*‘  匹配*号前的字符0次或多次,re.findall('ab*', 'cabb3abcbbac') 结果为['abb', 'ab', 'a']

        '+'  匹配前一个字符1次或多次,re.findall('ab+', 'ab+cd+abb+bba')结果['ab', 'abb']

        '?'  匹配钱一个字符1次或0次

        ’{m}‘ 匹配前一个字符m次

        ’{m,n}‘ 匹配前一个字符m到n次,re.findall('ab{1,3}', 'abb abc abbcbbb') 结果['abb', 'ab', abb]

       '|'  匹配|左或|右的字符,re.search('ab|ABC','ABCBabcCD') 结果['ABC']

        (...)  分组匹配,re.search('(abc){2}a(123|456)c', 'abcabca456c').group() 结果  abcabca456c

        \A    只从字符开头匹配,re.search('\Aabc', 'alexabc') 是匹配不到的,\A ==  ^

        \Z  匹配字符结尾,同$

        \d  匹配数字0-9

        \D  匹配非数字

        \w  匹配[A-Za-z0-9]

        \W  匹配非[A-Za-z0-9]

        \s    匹配空白字符,\t  \n  \r  ,re.search('\s' ,'ab\tc1\n3').group() 结果\t

        \b  类似与bash中\<      \>对单词做锚定

      (?P<name>....)  分组匹配re.search(’(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<hometown>[0-9{2}])(?P<birthday>[0-9]{8})‘, '

371481199306143242').groupdict()   结果是{’province‘: 37, 'city': 14, 'hometown': 81,'birthday': 19930614}

      最常用的匹配语法

re.match    从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换

      仅需轻轻知道的几个匹配模式

re.I(re.IGNORECASE):     忽略大小写(括号内是完整写法,下同)
M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
S(DOTALL): 点任意匹配模式,改变'.'的行为
import re

Match = re.search(r'\ber\b', ' i am er eraber')
print(Match.group())
#输出
er a = re.match('chen', 'chenronghuachenronghua') #有返回就是匹配到了,match从开头匹配
print(a.group())
#输出
chen a = re.match('k', 'chenronghuachenronghua')
print(a) #匹配不到,如果写a.group()会报错
匹配不到 a = re.match('chen\d', 'chen234ronghua1234chenronghua12431adec') #有返回就是匹配到了
print(a.group())
#输出
chen2 \d代表数字,匹配一次,如果表示一个或多个,使用\d+ a = re.match('.+', 'chen234ronghua1234chenronghua12431adec') #有返回就是匹配到了
print(a.group())
#输出
chen234ronghua1234chenronghua12431adec a = re.search('^chen', 'chen234ronghua1234ronghua12431adec') #匹配所有,但是找到第一个就返回
print(a.group())
#输出
chen a = re.search('^c.+n\d+', 'chen234ronghua1234ronghua12431adec') #已c开头,中间用多个任意字符,后面是一个数字\d,因为使用search所以只能匹配第一个匹配就返回
print(a.group())
#输出
chen234
a = re.findall('^c.+n\d+', 'chen234ronghua1234ronghua12431adec') #findall会匹配全部匹配到值
print(a)
#输出
['chen234'] a = re.findall('\+$', 'chen234ronghua1234ronghua12431adec') #findall会匹配全部匹配到值D \D表示匹配非数字但是会匹配特殊字符
print(a)
#输出
['adec'] a = re.search('a[a-zA-Z]+c$', 'chen234ronghua1234ronghua12431adec') #[a-zA-Z]表示匹配所有字符一次,加+表示1次到多次
print(a.group())
#输出
adec
a = re.search(r'\b#.+#$', '1123#hello#') #\b表示锚定字符
print(a.group())
#输出
#hello# a = re.findall(r'a?', 'abaalexa') # ?表示匹配前面字符0-1次
print(a)
#输出
['a', '', 'a', 'a', '', '', '', 'a', ''] a = re.search('[0-9]{3}','aa1x2a345aa') # {3}匹配 数字3次
print(a.group())
#输出
345 a = re.findall('[0-9]{1,3}','aa1x2a345aa') # {1,3}匹配 数字1-3次
print(a)
#输出
['', '', ''] a = re.findall('abc|ABC','abcdedaABCCDABC') #匹配abc或者ABC
print(a)
#输出
['abc', 'ABC', 'ABC'] a = re.findall('(abc){2}','abcabcABCabcdeabcabcdaedabcadedcad') #
print(a)
#输出
['abc', 'abc'] a = re.findall('\A[0-9]+[a-z]+\Z','103494abd') #\A 等效于^ \Z 等效于\
print(a)
#输出
['103494abd'] a = re.findall('\D','103494abd\t \n\\') #\D 匹配非数字包括字符和特殊格式
print(a)
#输出
['a', 'b', 'd', '\t', ' ', '\n', '\\'] a = re.findall('\w','103494abd\t \n\\') #\w 匹配数字和字母
print(a)
#输出
['', '', '', '', '', '', 'a', 'b', 'd'] a = re.findall('\W','103494abd\t \n\\') #\W匹配非数字和字母 表示特殊格式与空格
print(a)
输出
#['\t', ' ', '\n', '\\'] a = re.findall('\s','103494abd\t \n\\') #\s匹配特殊字符 空格 不包括 "\"
print(a)
#输出
['\t', ' ', '\n'] a = re.search('(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<hometown>[0-9]{2})(?P<birthday>[0-9]{8})', '')
print(a.groupdict())
输出
#{'province': '37', 'hometown': '81', 'city': '14', 'birthday': '19930614'} a = re.search('[a-z]+','abccdA', flags=re.I) #re.I 忽略大小写
print(a.group())
#输出
abccdA a = re.search('[a-z]+','abccdA', flags=re.I) #re.I 忽略大小写
print(a.group())
输出
abccdA a = re.search('[a-z]+d$','abccdA\nsecondline\nthird', flags=re.M) #re.M匹配换行
print(a.group())
#输出
third a = re.search('.+','oneline\nsecondline\nthird\nfourthline', flags=re.S) #在.中如何使用re.S可以连换行都能匹配上
print(a.group())
#输出
oneline
secondline
third
fourthline

    12、conllections模块

      1、Counter函数

        counter函数对字符串、列表进行分割,统计字符串出现的次数

import collections
obj = collections.Counter('abedjdjajdebaqazwsxedccvfredaa djdjejkd;ddoeeo;ddedpdkdkdk')#元素里出现次数记录,计数器功能
print(obj) #输出 Counter({'d': 16, 'e': 8, 'j': 6, 'a': 6, 'k': 4, 'o': 2, 'c': 2, ';': 2, 'b': 2, 'w': 1, 'q': 1, 'v': 1, 'z': 1, ' ': 1, 'f': 1, 'p': 1, 'r': 1, 'x': 1, 's': 1})
ret = obj.most_common(5) #输出前五个
print(ret)
#输出
[('d', 16), ('e', 8), ('j', 6), ('a', 6), ('k', 4)]
obj = collections.Counter([11,22,33,22,33])  #对列表进行统计
print(obj)
#输出
Counter({33: 2, 22: 2, 11: 1})
obj.update(['erc',11,11,22,11]) #对原有obj进行更新,添加数据
print(obj)
#输出
Counter({11: 4, 22: 3, 33: 2, 'erc': 1})
obj.subtract(['erc', 11,22,33,11])
print(obj)
#输出
Counter({11: 2, 22: 2, 33: 1, 'erc': 0})

      

      2、双向队列与单向队列

        deque表示双向队列,双向队列表示从右面与左面均可添加与消耗队列中的数据

import collections
d = collections.deque()
d.append('') #正常的append从右面添加,append可以添加单个元素
d.appendleft('') #从左面添加
d.appendleft('')
print(d)
#输出
deque(['', '', ''])
print(d.count(''))
#输出
2
d.extend(['aa','bb','aa']) #extend添加多个元素
print(d)
#输出
deque(['', '', '', 'aa', 'bb', 'aa'])
d.extendleft(['aa','bb','aa'])
print(d)
#输出
deque(['aa', 'bb', 'aa', '', '', '', 'aa', 'bb', 'aa'])

        单向队列只能从一侧添加一侧消耗

import queue
q = queue.Queue()
q.put('')
print(q.qsize())
#输出
1 q.put('')
print(q.qsize())
#输出
2 print(q.get())
#输出
123 print(q.get())
#输出
789

      3、可命名元组

import collections

M = collections.namedtuple('Mytuple', ['x','y','z'])
obj = M(11,22,33)
print(obj.x,obj.y,obj.z)
#输出
11 22 33

      

      4、有序字典

import collections
dic = collections.OrderedDict() #有序字典定义 dic['k1'] = 'v1'
dic['k2'] = 'v2'
dic['k3'] = 'v3' for i in dic:
print(i + '\t\t' + dic[i])
#输出®
k1 v1
k2 v2
k3 v3 dic.popitem()
print(dic)
#输出
OrderedDict([('k1', 'v1'), ('k2', 'v2')]) ret = dic.pop('k1')
print(dic)
print(ret)
#输出
OrderedDict([('k2', 'v2')])
v1
dic.setdefault('k2','') #如果没有就变成444,如果本身有值就不变
dic.setdefault('k4') #只有k4,就把值变为None
print(dic)
#输出
OrderedDict([('k2', 'v2'), ('k4', None)]) dic.update({'k2': 'v222', 'k10':'v10'}) #通过update方法添加多个元素,如果原来key存在会修改原value
print(dic)
#输出
OrderedDict([('k2', 'v222'), ('k4', None), ('k10', 'v10')])

      5、默认字典

import collections
dic = collections.defaultdict(list) #创建一个字典,字典的默认值为list dic['k1'].append('alex')
dic['k1'].extend(['gavin','age',23])
print(dic)
#输出
defaultdict(<class 'list'>, {'k1': ['alex', 'gavin', 'age', 23]}) dic1 = collections.defaultdict(dict) dic1['k1']['k1'] = 'v1'
dic1['k2']['k2'] = 'v2'
print(dic1)
#输出
defaultdict(<class 'dict'>, {'k2': {'k2': 'v2'}, 'k1': {'k1': 'v1'}})

    13、subprocess模块

      subprocess将代替os.system与os.spawn模块,在python2.7中,subprocess模块调用call()函数显示实时输出结果,通过Popen函数保存输出结果,在python3.5以后,通过run()代替call()函数

import subprocess

subprocess.run('df -h',shell=True)

a = subprocess.Popen('df -h',shell=True,stdout=subprocess.PIPE) #run与call和Popen都是如此,如果参数不止一个,同时也不想通过列表方式传入,需要shell=True
#如果需要保存输出结果,需要通过Popen函数保存,同时需要通过subprocess.PIPE管道方式将结果传递给输出
print(a.stdout.read())

    终端输入命令分为两种:

      1、输入即可得到输出  如ifconfig    

      2、输入进行某环境依赖再输入 如python

    需要交互命令实例:

    可以使用这个方法与另外一个子进程进行交互(配合管道PIPE来使用)

import subprocess
obj = subprocess.Popen(['python'], stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
obj.stdin.write('print 1 \n'.encode('utf-8'))
obj.stdin.write('print 2 \n'.encode('utf-8'))
obj.stdin.write('print 3 \n'.encode('utf-8'))
obj.stdin.write('print 4 \n'.encode('utf-8')) out_err_list = obj.communicate(timeout=10)#如果想结束进程,使用communicate函数
print(out_err_list)

    14、logging模块

      很多程序都有记录日志的需求,并且日志中包含的信息既有正常的程序访问日志,还可能有错误告警灯信息输出,python的logging模块提供了标准的日志接口,可以通过它存储各种格式的日志,logging的日志分为debug、info、warning、error5个等级

import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%s ', filename='example-log.log',level=logging.INFO)
#%S 表示正常秒 %s表示更精确的秒, %p表示 AM或者PM这个可以和%I一起使用
logging.debug('this message should go to the log files')
logging.info('so should this')
logging.warning('and this, too')

  10、二分法

def find_data(data,find_i):
if len(data) > 1:
if data[int(len(data)/2)] > find_i:
print(data[:int(len(data)/2)])
find_data(data[:int(len(data)/2)],find_i)
elif data[int(len(data)/2)] < find_i:
print(data[int(len(data)/2):])
find_data(data[int(len(data)/2):],find_i)
else:
print('find the number: %s' %data[int(len(data)/2)])
else:
if data[int(len(data)/2)] == find_i:
print('find the number: %s' %data[int(len(data)/2)])
else:
print('cant not find')
if __name__ == '__main__':
data = list(range(1,50,3))
find_data(data,5)

  

  11、冒泡排序

data = [10,4,33,21,22,54,3,8,11,5,22,17,13,6]
for j in range(1,len(data)):
for i in range(len(data)-j):
if data[i] > data[i+1]:
tmp = data[i]
data[i] = data[i+1]
data[i+1] = tmp print(data)

  12、时间复杂度

      时间复杂度是用来衡量算法的优劣,通常来讲,算法效率越高,时间复杂度消耗的时间越低,通常来说,时间复杂度分为O(n) 线性复杂度,O(n2)和O(n3),还有 O(1)和O(logn),其中O(1)为常量,不论数据量多大,都是同一时间完成,效率最高,而O(logn)的典型代表就是二分法和二叉树法,这种方法随着数据量越高,效率越高, O(n)为线性增长,随着数据量的增大而线性增大,最后是O(n2)  O(n3)分别代表算法中存在两次循环和三次循环,效率比前面的低

  13、深拷贝

    拷贝分为深拷贝与浅拷贝,其中copy.copy()与变量赋值均属于浅拷贝,浅拷贝的特点为只拷贝第一层数据,而不拷贝第一层以外的数据,这样的坏处在于修改了第一层以外的数据的拷贝数据时,原始数据也会跟着修改,而深拷贝会拷贝所有数据,无论数据处于第几层,这样拷贝数据与原始数据相互之间不受影响

import copy
'''
#浅拷贝 copy.copy() #深拷贝
copy.deepcopy() #赋值
a = '111'
b = a
'''
#赋值
a1 = 123
b1 = 123
print(id(a1))
print(id(b1)) a2 = a1
print(id(a1))
print(id(a2)) #字符串拷贝,对于字符串,深浅拷贝都只是指向内存都一地址
a3 = copy.copy(a1)
print(id(a3)) a4 = copy.deepcopy(a1)
print(id(a4)) #对元组/列表/字典拷贝 n1 = {'k1': 'wu', 'k2': 123, 'k3': ['alex',456]}
n2 = n1 #赋值
print(id(n1))
print(id(n2)) n3 = copy.copy(n1) #浅拷贝,只拷贝一层,所以n3只拷贝了k1 k2 k3对应的值,而k3中代表的列表没有进行拷贝
print(id(n3)) print(id(n3['k3'])) #由于浅拷贝只拷贝一层,所以n3与n1的k3对应的列表内存地址一样
print(id(n1['k3'])) n4 = copy.deepcopy(n1)
print(id(n4['k3']))
print(id(n4))

  

 

  

Python学习笔记第五周的更多相关文章

  1. python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹

    python学习笔记(五岁以下儿童) 深拷贝-浅拷贝 浅拷贝就是对引用的拷贝(仅仅拷贝父对象) 深拷贝就是对对象的资源拷贝 普通的复制,仅仅是添加了一个指向同一个地址空间的"标签" ...

  2. Python学习笔记(五)

    Python学习笔记(五): 文件操作 另一种文件打开方式-with 作业-三级菜单高大上版 1. 知识点 能调用方法的一定是对象 涉及文件的三个过程:打开-操作-关闭 python3中一个汉字就是一 ...

  3. [Python学习笔记][第五章Python函数设计与使用]

    2016/1/29学习内容 第四章 Python函数设计与使用 之前的几页忘记保存了 很伤心 变量作用域 -一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将这个赋值结果反映到函数之外,可 ...

  4. Python学习笔记第二十三周(Flask架构)

    目录: 一.变量引用 内容: 备注:PyCharm小技巧,comm+alt+l  自动修改格式,comm+alt+return  向上添加新行 一.变量引用 1.url生成 from flask im ...

  5. Python学习笔记第十周

    目录: 一.基础概念 1.多进程 2.进程间通信 3.进程锁 4.进程池 5.协程 a) greenlet b) Gevent 6.论事件驱动与异步IO 7.IO多路复用 8.Python Selec ...

  6. Python学习笔记(五)之Python操作Redis、mysql、mongodb数据库

    操作数据库 一.数据库 数据库类型主要有关系型数据库和菲关系型数据库. 数据库:用来存储和管理数的仓库,数据库是通过依据“数据结构”将数据格式化,以记录->表->库的关系存储.因此数据查询 ...

  7. Python学习笔记(五)——list和tuple

    一.list 1.定义: list是一种有序的集合,可以随时添加和删除其中的元素 2.声明方法: subjects=['Math','English', 'Chinese'] 3.一些api (1)获 ...

  8. python 学习笔记十五 web框架

    python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. Python的WEB框架分为两类: 自己写socket,自 ...

  9. python 学习笔记十五 django基础

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

随机推荐

  1. Java中获得当前静态类的类名

    通常在打印日志的时候需要输出类名,普通类可以用this.getClass(),但是静态类没有this,直接写类名耦合度高. 参考了: https://stackoverflow.com/questio ...

  2. 【LeetCode】Valid Parentheses合法括号

    给定一个仅包含 '('.')'.'{'.'}'.'['.']'的字符串,确定输入的字符串是否合法. e.g. "()"."()[]{}"."[()]( ...

  3. windows 常用dos命令

    explorer目录 打开当前目录 explorer . 打开上级目录 explorer .. 打开任意目录 explorer dirname cls 命令 清屏屏幕,屏幕显示的所有字符信息都是存放在 ...

  4. 整数中1出现的次数(1~n)

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  5. list的四种遍历方式

    1.手先增强for循环和iterator遍历的效果是一样的,也就说 增强for循环的内部也就是调用iteratoer实现的,但是增强for循环 有些缺点,例如不能在增强循环里动态的删除集合内容.不能获 ...

  6. 不同生产商的CPU以及大端/小端对齐

    ● 不同生产商的CPU以及大端/小端对齐 ※ ARM.AMD.Atom和intel之间的关系   intel公司和AMD公司生产的是相同的x86架构的CPU,这种CPU属于CISC(Complex I ...

  7. Android : 输入设备键值从底层到应用层的映射流程

    一.Android输入子系统简介: Android输入事件的源头是位于/dev/input/下的设备节点,而输入系统的终点是由WMS管理的某个窗口.最初的输入事件为内核生成的原始事件,而最终交付给窗口 ...

  8. Android : 修改内核源码 and 编译、打包成新的boot.img

    一.Android内核源码的下载: 1.Google GIT地址: $ git clone https://android.googlesource.com/kernel/common.git $ g ...

  9. 1080 MOOC期终成绩

    对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分的在线编程作业分,然后总评获得不少于60分( ...

  10. String转换成Boolean类型

    Boolean.valueOf()方法: public static Boolean valueOf(String s) { return toBoolean(s) ? TRUE : FALSE; } ...