python学习笔记_week5_模块

模块

一、定义:

模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),

本质就是.py结尾的python文件(文件名:test.py,对应模块名:test)

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

二、导入方法

import module_alex,

调用:print(module_alex.name)
   module_alex.say_hello()

导入多个模块:import module1_name,import module2_name

把module_alex中的所有代码导入:from module_alex import *(不建议使用*,

它的本质是复制maodule_alex中的代码到当前程序,变量有重复的话执行当前程序的变量)

from module_alex import logger as logger_alex (起个别名)

导入多个:from module_alex import m1,m2,m3

三、import本质(路径搜索和搜索路径)

python学习笔记_week5_模块

import module_alex将module_alex的所有代码解释一遍并赋值给一个变量module_alex,调用通过module_alex.***的形式

(import test  test="test.py all code")

(from test import name    name="code")

导入模块的本质就是把python文件解释一遍。

import module_alex--->module_alex.py(是文件就一定有路径)---->module_alex.py的路径---->sys.path(先在当前位置找,再在系统环境变量中找)

导入包的本质就是执行该包下面的__init__.py文件

四、导入优化

from module_test import test

python学习笔记_week5_模块

main.py

 import sys,os
print(sys.path) x=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(x)
import module_alex
module_alex.say_hello()

main

__init__.py

 print("from the package_test")

 #import test1 #test="test1.py all code".test1.test()
from.import test1 #相对导入,从当前目录下导入test1,相对于__init__的路径

init

test1.py

 def test():
print("in the test1")

test1

module_test.py

 def test():
print("in the module_test")

module_test

test.py

 import module_test
#from module_test import test
def logger():
module_test.test()
print('in the logger') def search():
module_test.test()
print("in the search")

test

module_alex.py

 name="alex"
def say_hello():
print("hello alex")
def logger():
pass
def running():
pass

module_alex

p_test.py

 import package_test
#1.run __init__.py--->test1="test1.py all code".test1 package_test.test1.test()

p_test

五、模块的分类:

a:标准库(内置模块)、b:开源模块(第三方模块)、c:自定义模块

1.time与datetime

在Python中,通常有这几种方式来表示时间:1)时间戳2)格式化的时间字符串3)元组(struct_time)共九个元素。由于Python的time模块实现主要调用C库,所以各个平台可能有所不同。

UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8。DST(Daylight Saving Time)即夏令时。

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

python学习笔记_week5_模块

元组(struct_time)方式:struct_time元组共有9个元素,返回struct_time的函数主要有gmtime(),localtime(),strptime()。

import time
print(time.localtime())
'''--->time.struct_time(tm_year=2017, tm_mon=10, tm_mday=24,
tm_hour=10, tm_min=36, tm_sec=20, tm_wday=1, tm_yday=297, tm_isdst=0)''' time:
 import time
print(time.localtime())
'''--->time.struct_time(tm_year=2017, tm_mon=10, tm_mday=24,
tm_hour=10, tm_min=36, tm_sec=20, tm_wday=1, tm_yday=297, tm_isdst=0)''' #Variables:
print(help(time))
print(time.timezone) # difference in seconds between UTC and local standard time
print(time.altzone) #difference in seconds between UTC and local DST time
print(time.daylight) #whether local time should reflect DST
#Functions:
print(time.time()) # return current time in seconds since the Epoch as a float
time.sleep(2) # delay for a number of seconds given as a float
print(time.gmtime())#将时间戳转化为struct_time,不传入参数的话将本地时间换算成UCT时间,传入参数的话,"1970"+参数
print(time.localtime())#将时间戳转化为struct_time,不传入参数的话就是本地时间,传入参数同上,不过hour+8 x=time.localtime()
print(x.tm_year) #提取"年" print(time.mktime(x)) #元组形式转化为时间戳
print(time.strftime("%Y-%m-%d %H:%M:%S",x)) #元组形式转化为格式化字符串
#%Y相当于x.tm_year %m相当于x.tm_mon
print(time.strptime("2017-10-24 13:36:46","%Y-%m-%d %H:%M:%S")) #格式化字符串转化为元组形式
#以后面的格式到前边找对应的值,x.tm_year=2017,x.tm_mon=10 print(time.asctime())#将元组转化为字符串的格式,不写参数传入的就是本地时间
print(time.ctime())#将时间戳转化为字符串的格式,不写参数传入的就是本地时间 import datetime
print(datetime.datetime.now()) # 返回 2017-10-24 14:52:46.098161
print(datetime.date.fromtimestamp(time.time()) ) # 时间戳直接转成日期格式 2017-10-24
print("-----")
print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
print("-----")
c_time = datetime.datetime.now()
print(c_time.replace(minute=3,hour=12)) #时间替换

time

strftime(“格式”,struct_time)--->“格式化的字符串”
strptime(“格式化的字符串”,“格式”)--->struct_time

python学习笔记_week5_模块

格式参照:

%a    本地(locale)简化星期名称    
%A    本地完整星期名称    
%b    本地简化月份名称    
%B    本地完整月份名称    
%c    本地相应的日期和时间表示    
%d    一个月中的第几天(01 - 31)    
%H    一天中的第几个小时(24小时制,00 - 23)    
%I    第几个小时(12小时制,01 - 12)    
%j    一年中的第几天(001 - 366)    
%m    月份(01 - 12)    
%M    分钟数(00 - 59)    
%p    本地am或者pm的相应符       
%S    秒(01 - 61)        
%U    一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。       
%w    一个星期中的第几天(0 - 60是星期天)        
%W    和%U基本相同,不同的是%W以星期一为一个星期的开始。    
%x    本地相应日期    
%X    本地相应时间    
%y    去掉世纪的年份(00 - 99)    
%Y    完整的年份    
%Z    时区的名字(如果不存在为空字符)    
%%    %’字符
 
 

2.random模块

 import random
print(random.random())#随机浮点值0-1之间 print(random.randint(1,3))#随机1-3之间的整数,3能取到
#random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。
# 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b print(random.randrange(1,3))#随机1-3之间的整数,3不能取到,1能取到
#random.randrange的函数原型为:random.randrange([start], stop[, step]),
# 从指定范围内,按指定基数递增的集合中 获取一个随机数。如:random.randrange(10, 100, 2),
# 结果相当于从[10, 12, 14, 16, ... 96, 98]序列中获取一个随机数。
# random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。 print(random.choice("hello"))#序列,字符串,列表,元组
# 其函数原型为:random.choice(sequence)。参数sequence表示一个有序类型。
# 这里要说明一下:sequence在python不是一种特定的类型,而是泛指一系列的类型。
# list, tuple, 字符串都属于sequence。有关sequence可以查看python手册数据模型这一章。 print(random.sample("hello",4))#第一个变量序列,字符串,列表,元组,第二个定义一个长度,随机取几位返回
#random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。
list = [1, 2, 3, 4, 5, 6, 7, 8]
slice = random.sample(list, 5) # 从list中随机获取5个元素,作为一个片断返回
print(slice)
print(list) # 原有序列并没有改变 print(random.uniform(1,3))#random不能指定区间,uniform可以指定 l=[1,2,3,4,5,6]
random.shuffle(l)#洗牌功能
print(l)
print("------")
import random
# 随机整数:
print(random.randint(0, 99)) #
# 随机选取0到100间的偶数:
print(random.randrange(0, 101, 2)) #
# 随机浮点数:
print(random.random()) # 0.2746445568079129
print(random.uniform(1, 10)) # 9.887001463194844
# 随机字符:
print(random.choice('abcdefg&#%^*f')) # f
# 多个字符中选取特定数量的字符:
print(random.sample('abcdefghij', 3)) # ['f', 'h', 'd']
# 随机选取字符串:
print(random.choice(['apple', 'pear', 'peach', 'orange', 'lemon'])) # apple
# 洗牌#
items = [1, 2, 3, 4, 5, 6, 7]
print(items) # [1, 2, 3, 4, 5, 6, 7]
random.shuffle(items)
print(items) # [1, 4, 7, 2, 5, 3, 6]
print("======")
#验证码
checkcode=""
for i in range(4):
#i=0
current=random.randrange(0,4)
#字母
if current==i:
tmp=chr(random.randint(65,90))
#数字
else:
tmp=random.randint(0,9)
checkcode+=str(tmp)
print(checkcode)

random

3.os模块

 import os
print(os.getcwd())#获取当前工作目录,即当前python脚本工作的目录路径
# os.chdir("E:\\pycharm\\s14\\")
os.chdir(r"E:\pycharm\s14")
print(os.getcwd())# 改变当前脚本工作目录;相当于shell下cd
print(os.curdir) # 返回当前目录: ('.')
print(os.pardir) #获取当前目录的父目录字符串名:('..')
#os.makedirs(r'E:\a\b\c\d') # 可生成多层递归目录
#os.removedirs(r'E:\a\b\c\d') #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推,清理空文件夹
#os.mkdir(r'E:\a\b') # 生成单级目录;相当于shell中mkdir dirname
#os.rmdir(r'E:\a\b') # 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
print(os.listdir(".")) #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印-->
# ['.idea', 'day1', 'day2', 'day3', 'day4', 'day5']
#os.remove() # 删除一个文件
#os.rename(r"E:\pycharm\s14\day5\y_test.py",r"E:\pycharm\s14\day5\p_test.py") #重命名文件/目录
print(os.stat('day5')) #获取文件/目录信息
print(os.sep)#输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
print(os.linesep) # 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
#print(os.environ)#获取系统环境变量
print(os.pathsep) #输出用于分割文件路径的字符串 windows中';'
print(os.name) #输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
#os.system("dir") #运行shell命令,直接显示
#os.system("ipconfig /all")
print(os.path.abspath(r"E:\pycharm\day5\os_moduel\os.py")) #返回规范化的绝对路径
print("=====")
print(os.path.split(r"E:\a\b\c\d.txt")) # 将path分割成目录和文件名二元组返回
print(os.path.dirname(r"E:\a\b\c\d.txt")) #返回path的目录。其实就是os.path.split("path")的第一个元素
print(os.path.basename(r"E:\a\b\c\d.txt")) # 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。
# 即os.path.split("path")的第二个元素
#以上三中方法都可以在目录不存在的情况下进行
print(os.path.exists(r"E:\a")) # 如果path存在,返回True;如果path不存在,返回False
print(os.path.isabs(r"a\b")) # 如果path是绝对路径,返回True
print(os.path.isfile(r"E:\a\1.txt")) # 如果path是一个存在的文件,返回True。否则返回False,不存在文件False
print(os.path.isdir(r"E:\a")) # 如果path是一个存在的目录,则返回True。否则返回False,不存在目录False
print(os.path.join(r"C:",r"a",r"b",r"a.txt"))# 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
print(os.path.getatime(r"E:\a\1.txt")) # 返回path所指向的文件或者目录的最后存取时间 ,文件必须存在
print(os.path.getmtime(r"E:\a\1.txt") ) #返回path所指向的文件或者目录的最后修改时间

os_

更多https://docs.python.org/2/library/os.html?highlight=os#module-os

4.sys模块

python学习笔记_week5_模块

 import sys
print(sys.argv) # 命令行参数List,,在终端运行后加参数,第一个元素是程序本身路径
#print(sys.exit()) #退出程序,正常退出时exit(0)
print(sys.version) #获取Python解释程序的版本信息
print(sys.maxsize)
print(sys.path) #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
print(sys.platform) #返回操作系统平台名称
print(sys.stdout.write('please:'))
val = sys.stdin.readline()[:-1]

sys_

5.shutil模块

http://www.cnblogs.com/wupeiqi/articles/4963027.html

高级的 文件、文件夹、压缩包 处理模块

shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中,可以部分内容

shutil.copyfile(src, dst)
拷贝文件

shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变

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

shutil.copy(src, dst)
拷贝文件和权限

shutil.copy2(src, dst)
拷贝文件和状态信息

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件

例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件

shutil.move(src, dst)
递归的去移动文件

shutil.make_archive(base_name, format,...)

创建压缩包并返回文件路径,例如:zip、tar

  • base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    如:www                        =>保存至当前路径
    如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
  • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要压缩的文件夹路径(默认当前目录)
  • owner: 用户,默认当前用户
  • group: 组,默认当前组
  • logger: 用于记录日志,通常是logging.Logger对象

shutil 对压缩包的处理是调用 zipfile 和 tarfile 两个模块来进行的,详细:

 import zipfile

 # 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close() # 解压
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall()
z.close()

zipfile

 import tarfile

 # 压缩
tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip')
tar.close() # 解压
tar = tarfile.open('your.tar','r')
tar.extractall() # 可设置解压地址
tar.close()

tarfile

 import shutil
# f1=open("本节笔记",encoding="utf-8")
# f2=open("笔记2","w",encoding="utf-8")
# shutil.copyfileobj(f1,f2) #shutil.copyfile("笔记2","笔记3") #shutil.make_archive("shutil_archive_test","zip","E:\pycharm\s14\day5") import zipfile
z = zipfile.ZipFile("day5.zip","w")
z.write("p_test.py")
print("---")
z.write("笔记2")
z.close()

shutil_

6.shelve模块

shelve模块是一个简单的key-value将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。python学习笔记_week5_模块

 import shelve,datetime

 d = shelve.open('shelve_test')  # 打开一个文件

 # info={"age":22,"salary":"50w"}
#
# name = ["alex", "rain", "test"]
# d["test"] = name # 持久化列表
# d["name"] = name # 持久dict
# d["info"] =info
# d["date"]=datetime.datetime.now()
# d.close() print(d.get("name"))
print(d.get("info"))
print(d.get("date"))

shelve_

7.xml模块

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,

大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

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

 <?xml version='1.0' encoding='utf-8'?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year updated_by="alex">2009</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year updated_by="alex">2012</year>
<gdppc>59900</gdppc>
<neighbor direction="N" name="Malaysia" />
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year updated_by="alex">2012</year>
<gdppc>13600</gdppc>
<neighbor direction="W" name="Costa Rica" />
<neighbor direction="E" name="Colombia" />
<info>
<population>8</population>
<size>960</size>
</info>
</country>
</data>

格式

xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml

 import xml.etree.ElementTree as ET

 tree = ET.parse("xmltest.xml") #写上要处理的文件名
root = tree.getroot()
print(root)
print(root.tag) #标签名 # 遍历xml文档
for child in root:
print(child.tag, child.attrib) #子标签,attrib属性
for i in child:
print(i.tag, i.text)
for j in i:
print(j.tag,j.text) # # 只遍历year 节点
# for node in root.iter('year'):
# print(node.tag, node.text)

xml_handle

修改和删除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 #把年+1
# node.text = str(new_year)
# node.set("updated_by", "alex") #加属性
#
# 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_modify

自己创建xml文档

 import xml.etree.ElementTree as ET

 new_xml = ET.Element("personinfolist") #根节点
personinfo = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "yes"}) #new_xml的子节点
name = ET.SubElement(personinfo, "name")
name.text="alex"
age = ET.SubElement(personinfo, "age", attrib={"checked": "no"})#personinfo的子节点
sex = ET.SubElement(personinfo, "sex")
age.text = ''#赋值
personinfo2 = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "no"})
name = ET.SubElement(personinfo2, "name")
name.text="jyh"
age = ET.SubElement(personinfo2, "age")
age.text = '' et = ET.ElementTree(new_xml) # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True) #xml_declaration=True,声明xml格式 ET.dump(new_xml) # 打印生成的格式

xml_create

8.PyYAML模块

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

9.ConfigParser模块

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

来看一个好多软件的常见文档格式如下(与MySQL格式一样)

 [DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes [bitbucket.org]
User = hg [topsecret.server.com]
Port = 50022
ForwardX11 = no

conf

如果想用python生成一个这样的文档怎么做呢?

 import configparser #ConfigParser in python 2.x

 config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '',
'Compression': 'yes',
'CompressionLevel': ''} config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg' config['topsecret.server.com'] = {}
config['topsecret.server.com']['Host Port'] = '' # mutates the parser
config['topsecret.server.com']['ForwardX11'] = 'no' # same here config['DEFAULT']['ForwardX11'] = 'yes' with open('example.ini', 'w') as configfile:
config.write(configfile)

conf_create

写完了还可以再读出来哈。

 >>> import configparser
>>> config = configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read('example.ini')
['example.ini']
>>> config.sections()
['bitbucket.org', 'topsecret.server.com']
>>> 'bitbucket.org' in config
True
>>> 'bytebong.com' in config
False
>>> config['bitbucket.org']['User']
'hg'
>>> config['DEFAULT']['Compression']
'yes'
>>> topsecret = config['topsecret.server.com']
>>> topsecret['ForwardX11']
'no'
>>> topsecret['Port']
''
>>> for key in config['bitbucket.org']: print(key)
...
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config['bitbucket.org']['ForwardX11']
'yes'

conf_read

configparser增删改查语法

 [section1]
k1 = v1
k2:v2 [section2]
k1 = v1 import ConfigParser config = ConfigParser.ConfigParser()
config.read('i.cfg') # ########## 读 ##########
#secs = config.sections()
#print secs
#options = config.options('group2')
#print options #item_list = config.items('group2')
#print item_list #val = config.get('group1','key')
#val = config.getint('group1','key') # ########## 改写 ##########
#sec = config.remove_section('group1')
#config.write(open('i.cfg', "w")) #sec = config.has_section('wupeiqi')
#sec = config.add_section('wupeiqi')
#config.write(open('i.cfg', "w")) #config.set('group2','k1',11111)
#config.write(open('i.cfg', "w")) #config.remove_option('group2','age')
#config.write(open('i.cfg', "w"))

conf_handle

10.hashlib模块

用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法(都是基于hash的,SHA比MD5更安全)

 import hashlib
m=hashlib.md5()
m.update(b"Hello")
print(m.hexdigest()) #16进制的格式
m.update("It's me天王盖地虎".encode(encoding="utf-8")) #实际上是“HelloIt's me天王盖地虎”
print(m.hexdigest())
#m.update(b"It's been a long time since we spoken...")
#print(m.hexdigest()) m2=hashlib.md5()
m2.update(b"HelloIt's me")
print(m.hexdigest()) s2=hashlib.sha1()
s2.update(b"HelloIt's me")
print(s2.hexdigest())
print("====")
import hmac
h=hmac.new(b"","you are 250你是".encode(encoding="utf-8"))#在3.0里,encode一下就是bytes了
print(h.hexdigest())

hashlib_handle

 import hashlib

 m = hashlib.md5()
m.update(b"Hello")
m.update(b"It's me")
print(m.digest())
m.update(b"It's been a long time since last time we ...") print(m.digest()) #2进制格式hash
print(len(m.hexdigest())) #16进制格式hash
'''
def digest(self, *args, **kwargs): # real signature unknown
""" Return the digest value as a string of binary data. """
pass def hexdigest(self, *args, **kwargs): # real signature unknown
""" Return the digest value as a string of hexadecimal digits. """
pass '''
import hashlib # ######## md5 ######## hash = hashlib.md5()
hash.update('admin')
print(hash.hexdigest()) # ######## sha1 ######## hash = hashlib.sha1()
hash.update('admin')
print(hash.hexdigest()) # ######## sha256 ######## hash = hashlib.sha256()
hash.update('admin')
print(hash.hexdigest()) # ######## sha384 ######## hash = hashlib.sha384()
hash.update('admin')
print(hash.hexdigest()) # ######## sha512 ######## hash = hashlib.sha512()
hash.update('admin')
print(hash.hexdigest())

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

散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;

一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,

这样就能验证消息的真实性,及发送者的合法性了。

 import hmac
h = hmac.new(b'天王盖地虎', b'宝塔镇河妖')
print h.hexdigest()

更多关于md5,sha1,sha256等介绍的文章看这里https://www.tbs-certificates.co.uk/FAQ/en/sha256.html

11.正则表达式

使用不难,难在匹配格式。爬虫需要精通。

python学习笔记_week5_模块又返回就匹配到了,没反应就没有匹配到

python学习笔记_week5_模块前边是格式,后边是字符串(套路)

常用正则表达式符号

 '.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",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次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\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' '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","").groupdict("city") 结果{'province': '', 'city': '', 'birthday': ''}

re

python学习笔记_week5_模块match套路从开头搜索,search套路从整个文本中搜索

python学习笔记_week5_模块python学习笔记_week5_模块python学习笔记_week5_模块多个匹配到第一个就返回

python学习笔记_week5_模块

python学习笔记_week5_模块python学习笔记_week5_模块python学习笔记_week5_模块

python学习笔记_week5_模块findall套路python学习笔记_week5_模块

python学习笔记_week5_模块python学习笔记_week5_模块

python学习笔记_week5_模块

========================================

python学习笔记_week5_模块python学习笔记_week5_模块

========================================

split套路

python学习笔记_week5_模块

sub套路

python学习笔记_week5_模块

最常用的匹配语法:

1.re.match 从头开始匹配

2.re.search 匹配包含
3.re.findall 把所有匹配到的字符放到以列表中的元素返回
4.re.splitall 以匹配到的字符当做列表分隔符
5.re.sub      匹配字符并替换
反斜杠的困扰

  与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",

那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,

转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。

同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

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

1.re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
2.M(MULTILINE): 多行模式,改变'^''$'的行为
3.S(DOTALL): 点任意匹配模式,改变'.'的行为
 
python学习笔记_week5_模块python学习笔记_week5_模块

本节作业

开发一个简单的python计算器

  1. 实现加减乘除及拓号优先级解析
  2. 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,
  3. 必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致

思路:

1.先用正则表达式匹配到最里层的括号所包括的不带括号的表达式

2.再把数据量变小(判断里面是否有括号,把加减运算和乘除运算单独放到两个函数里去做)

hint:

re.search(r'\([^()]+\)',s).group()

'(-40/5)'

上一篇:《android开发艺术探索》读书笔记(八)--WindowManager


下一篇:python_cookie