1、什么是模块

模块就是一系列功能的集合体,在python当中,一个py文件就是一个模块,例如:spam.py 就是一个模块,其中spam就是模块名,可以通过“import  spam”来调用

模块主要分为三个部分:

1、内置模块,例如 “time”,“os”等python解释器当中内置

2、自己用python编写的py文件

3、下载别人已经编写好的模块导入自己文件当中(这种拿来主义可以大大提高我们的开发效率)

在我们最开始学习python开始只是使用简单的数据类型和一些流程控制就可以开始编写一些简单的程序,但是这种编写方式在代码量大的情况下就很不方便,后来我们又学习了函数可以将重复的功能定义成函数,通过函数名就可以来重复的调用,但是我们不可能将所有的功能全部都放到一个文件当中,这就需要用到模块,将一些功能分别编写到不同的文件当中,通过import调用,这样从文件级别来组织程序会让程序的条理更加清晰,更加方便管理,也能实现功能的重复利用

2、import的使用

#模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句)

#test.py
import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
import spam
import spam
import spam

'''
执行结果:
from the spam.py
'''

import首次导入模块的三道程序:

1、创建一个模块的名称空间

   这个名称空间属于全局名称空间一级别的

2、执行模块对应的文件,将产生的名字存放于 “ l ” 的名称空间

3、在当前执行的文件中拿到一个文件名,以该文件名来引用该名称空间

  这个名字和变量名没什么区别,与全局变量属于一个级别,且使用spam.名字的方式

可以访问spam.py文件中定义的名字,spam.名字与test.py中的名字来自

两个完全不同的地方

因为import导入摸块所创建的名称空间属于全局名称空间一级别的,所以我们在导入模块中的名字时不必担心会被执行文件当中的名字冲突掉

2.1、为模块起别名

为已经导入的模块起别名的方式对编写可扩展的代码很有用

1 import spam as sm
2 print(sm.money)

有两中sql模块mysql和oracle,根据用户的输入,选择不同的sql功能

# mysql.py
def parse():
    print('hello world')
#  oracle.py
def parse():
    print('HELLO WORLD')

# 执行文件
# inp=input('>>:').strip()
# if inp=='mysql':
#     import mysql as db
# elif inp=='oracle':
#     import oracle as db
# db.parse()

import导入模块还可以一行导入多个模块

import sys,os,re   #(这种方式不建议多用)

2.2、from...import

在使用from...import时执行时与import执行前两件事一样

第三步是:在当前名称空间中直接拿到模块中的名字,可以直接使用,不用任何前缀

# from mysql import parse
# parse()

优点:使用比import更加方便

缺点:容易与当前执行文件当中的名字产生冲突

在from...import当中与import当中一样支持用  “ as ” 来为模块起别名,一行导入多个模块

当一个模块当中有多样功能的时候,我们可以使用  “ from... import  *  ”来将模块当中所有不是以下划线开头的全部导入当前位置

但是这种当时的可读性非常差,我们没有办法分清我们导入了哪些名字

这种时候我们可以使用  “ __all__ ” 来控制  “  *  ” 的范围

#  在模块中新增一行
__all__=['money','read1'] #这样在另外一个文件中用from spam import *就这能导入列表中规定的两个名字

3、模块的查找顺序

1、内存中已经加载的模块

2、内置模块

3、sys.path路径中包含的模块

sys.path的第一个路径是当前执行的文件夹

Python中spam python中spam函数_序列化

Python中spam python中spam函数_序列化_02

#模块的查找顺序
1、在第一次导入某个模块时(比如spam),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用
    ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看
2、如果没有,解释器则会查找同名的内建模块
3、如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。


#sys.path的初始化的值来自于:
The directory containing the input script (or the current directory when no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
The installation-dependent default.

#需要特别注意的是:我们自定义的模块名不应该与系统内置模块重名。虽然每次都说,但是仍然会有人不停的犯错。 

#在初始化后,python程序可以修改sys.path,路径放到前面的优先于标准库被加载。
1 >>> import sys
2 >>> sys.path.append('/a/b/c/d')
3 >>> sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索
注意:搜索时按照sys.path中从左到右的顺序查找,位于前的优先被查找,sys.path中还可能包含.zip归档文件和.egg文件,python会把.zip归档文件当成一个目录去处理,

#首先制作归档文件:zip module.zip foo.py bar.py 
import sys
sys.path.append('module.zip')
import foo,bar

#也可以使用zip中目录结构的具体位置
sys.path.append('module.zip/lib/python')


#windows下的路径不加r开头,会语法错误
sys.path.insert(0,r'C:\Users\Administrator\PycharmProjects\a')
 

#至于.egg文件是由setuptools创建的包,这是按照第三方python库和扩展时使用的一种常见格式,.egg文件实际上只是添加了额外元数据(如版本号,依赖项等)的.zip文件。

#需要强调的一点是:只能从.zip文件中导入.py,.pyc等文件。使用C编写的共享库和扩展块无法直接从.zip文件中加载(此时setuptools等打包系统有时能提供一种规避方法),且从.zip中加载文件不会创建.pyc或者.pyo文件,因此一定要事先创建他们,来避免加载模块是性能下降。

详细

4、软件开发目录

我们学习编程开始都是将所有的代码全部都放到一个文件里面,后来我们学习函数,模块之后才会说将自己程序的功能具体分一下类,但是因为我们写的程序是需要用户来使用的,对于怎样编程,怎样分类他们都是不了解的,这就需要我们对于软件或者说是程序的开发有一个明确的目录,让不管是自己还是维护人员都可以知道这个程序的大体内容。目录大概结构如下:

Python中spam python中spam函数_序列化_03

 

对于目录的具体分类大体有以下几类:

1、bin:启动目录,里面只需要有一个启动程序即可,所有文件的启动都由这里开始

2、conf:配置目录,里面是关于程序运行的所有配置文件,例如路径配置,日志配置等

3、core:主体目录,程序的主体架构,所有的核心逻辑

4、db:文件目录:在程序运行当中需要用到的一些文件

5、lib:工具目录,常用的工具,模块

6、log:日志目录,所有的日志文件

7、readme:关于程序的介绍(相当于说明书)

这样分类不仅自己在程序的编写上更加方便,也使得其他的工作人员可以一目了然,有利于后期对程序的更新与维护

5、包

简介:

#官网解释
Packages are a way of structuring Python’s module namespace by using “dotted module names”
包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

具体介绍:包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来
创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块
包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来随着功能越写越多,我们无法将所以功能都放到一个文件中,于是我们使用模块去组织功能,
而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性

注意事项:
#1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,

否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用

点的方式调用自己的属性)。

#2、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

#3、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

5.1、包的使用

执行文件必须与包所在的文件在同级目录下

import使用

1 import glance.db.models
2 glance.db.models.register_models('mysql')

在我们单独导入包名称时不会导入包中所包含的所有子模块,我们需要在  “ __init__.py  ” 文件下导入同级文件的子目录

from...import的使用

模块之间的导入应该使用from...improt

需要注意的是from后import导入的模块,必须是明确的一个名字,没有任何前缀,否则会有语法错误,如:from a import b.c是错误语法

1 from glance.db import models
2 models.register_models('mysql')
3 
4 from glance.db.models import register_models
5 register_models('mysql')

绝对导入和相对导入

我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

绝对导入:以glance作为起始

相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

1 在glance/api/version.py
2 
3 #绝对导入
4 from glance.cmd import manage
5 manage.main()
6 
7 #相对导入
8 from ..cmd import manage
9 manage.main()

包以及包所包含的模块都是用来被导入的,而不是被直接执行的。而环境变量都是以执行文件为准的

6、常用摸块

6.1、logging模块

 在我们平时编写的程序,基本上都会有记录日志的需求,并且日志当中包含的内容既有正常的程序访问,又有错误,警告等信息输出,在python的logging模块当中就提供了标准的日志接口,可以通过它来存储各种格式的日志,其中logging模块也分为五个等级:

debug(),info(),warning(),error(),critical(),其中默认级别为warning,默认打印到终端

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''

为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

Python中spam python中spam函数_序列化

View Code

Python中spam python中spam函数_序列化

View Code

logging模块的四大对象:Formatter,Handler,Logger,Filter

#logger:产生日志的对象

#Filter:过滤日志的对象

#Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端

#Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式

Python中spam python中spam函数_序列化

View Code

Logger是第一级过滤,只有Logger过滤之后,才会得到Handler

Python中spam python中spam函数_序列化

View Code

具体应用(以后工作当中也可以直接copy使用)

Python中spam python中spam函数_序列化

logging配置文件

6.2、json、pickle

 众所周知,在内存中是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。这就需要我们将内存当中的数据存到硬盘当中,以便下次程序执行能够从文件当中载入之前的数据,然后继续执行,这种行为就叫做序列化,序列化也可以说是我们把对象(变量)从内存中变成可存储或传输的过程。

序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

而在python当中的json模块,pickle模块就是为我们提供序列化功能的模块。

json

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

import json
 
dic={'name':'alvin','age':23,'sex':'male'}
print(type(dic))#<class 'dict'>
 
j=json.dumps(dic)
print(type(j))#<class 'str'>
 
 
f=open('序列化对象','w')
f.write(j)  #-------------------等价于json.dump(dic,f)
f.close()
#-----------------------------反序列化<br>
import json
f=open('序列化对象')
data=json.loads(f.read())#  等价于data=json.load(f)

Python中spam python中spam函数_序列化

注意内容

pickle

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

import pickle
 
dic={'name':'alvin','age':23,'sex':'male'}
 
print(type(dic))#<class 'dict'>
 
j=pickle.dumps(dic)
print(type(j))#<class 'bytes'>
 
 
f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'
f.write(j)  #-------------------等价于pickle.dump(dic,f)
 
f.close()
#-------------------------反序列化
import pickle
f=open('序列化对象_pickle','rb')
 
data=pickle.loads(f.read())#  等价于data=pickle.load(f)
 
 
print(data['age'])

6.3、os模块

os模块的官方解释:This module provides a portable way of using operating system dependent functionality.

这个模块提供了一种方便的使用操作系统函数的方法。 

Python中spam python中spam函数_序列化

功能表

os路径处理
#方式一:推荐使用
import os
#具体应用
import os,sys
possible_topdir = os.path.normpath(os.path.join(
    os.path.abspath(__file__),
    os.pardir, #上一级
    os.pardir,
    os.pardir
))
sys.path.insert(0,possible_topdir)


#方式二:不推荐使用
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

 很多人在有些时候会分不清os模块和sys模块的区别,其实总结来说,os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。

6.4、time和datetime

在Python中,通常有这几种方式来表示时间:

  • 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
  • 格式化的时间字符串(Format String)
  • 结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
import time
#--------------------------我们先以当前时间为准,让大家快速认识三种形式的时间
print(time.time()) # 时间戳:1487130156.419527
print(time.strftime("%Y-%m-%d %X")) #格式化的时间字符串:'2017-02-15 11:40:53'

print(time.localtime()) #本地时区的struct_time #例:time.struct_time(tm_year=2018, tm_mon=6, tm_mday=5, tm_hour=20, tm_min=52, tm_sec=24, tm_wday=1, tm_yday=156, tm_isdst=0)
print(time.gmtime())    #UTC时区的struct_time #例:time.struct_time(tm_year=2018, tm_mon=6, tm_mday=5, tm_hour=12, tm_min=52, tm_sec=24, tm_wday=1, tm_yday=156, tm_isdst=0)

Python中spam python中spam函数_序列化

View Code

三种时间表示方式转换关系:

Python中spam python中spam函数_python_12

Python中spam python中spam函数_序列化

转换关系

 

 

Python中spam python中spam函数_Python中spam_14

Python中spam python中spam函数_序列化

转换关系

 

Python中spam python中spam函数_序列化

datetime模块

6.5、random模块

生成随机数

import random
 
print(random.random())#(0,1)----float    大于0且小于1之间的小数
 
print(random.randint(1,3))  #[1,3]    大于等于1且小于等于3之间的整数
 
print(random.randrange(1,3)) #[1,3)    大于等于1且小于3之间的整数
 
print(random.choice([1,'23',[4,5]]))#1或者23或者[4,5]
 
print(random.sample([1,'23',[4,5]],2))#列表元素任意2个组合
 
print(random.uniform(1,3))#大于1小于3的小数,如1.927109612082716 
 
 
item=[1,3,5,7,9]
random.shuffle(item) #打乱item的顺序,相当于"洗牌"
print(item)

Python中spam python中spam函数_序列化

生成随机验证码

6.6、sys模块

sys模块官方解释:This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter.

这个模块可供访问由解释器使用或维护的变量和与解释器进行交互的函数。

sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n)        退出程序,正常退出时exit(0)
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操作系统平台

Python中spam python中spam函数_序列化

打印进度条

6.7、shutil模块

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

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

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

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

1、base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,

如 data_bak                       =>保存至当前路径

如:/tmp/data_bak =>保存至/tmp/

2、format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”

3、root_dir: 要压缩的文件夹路径(默认当前目录)

4、owner: 用户,默认当前用户

5、group: 组,默认当前组

6、logger: 用于记录日志,通常是logging.Logger对象

#将 /data 下的文件打包放置当前程序目录
import shutil
ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
  
  
#将 /data下的文件打包放置 /tmp/目录
import shutil
ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')

6.8、shelve模块

shelve模块相对于其他模块会简单一点,它只有一个“open”函数,与pickle模块相比会比较简单,它在返回对象的时候返回的是字典,可以读可以写,其中key必须是由字符串组成的,值是python所支持的数据类型

import shelve

f=shelve.open(r'sheve.txt')
# f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']}
# f['stu2_info']={'name':'gangdan','age':53}
# f['school_info']={'website':'http://www.pypy.org','city':'beijing'}

print(f['stu1_info']['hobby'])
f.close()

6.9、xml模块

xml模块所实现的功能与json模块所实现的功能相似,可以进行多语言交互,但是相对来说json的使用方法会比较简单,所以大部分人现在的数据交互功能使用的都是json模块,xml模块是通过<>来区分数据结构

Python中spam python中spam函数_序列化

xml格式

在python当中可以使用以下模块操作xml

# print(root.iter('year')) #全文搜索
# print(root.find('country')) #在root的子节点找,只找一个
# print(root.findall('country')) #在root的子节点找,找所有

 

Python中spam python中spam函数_序列化

View Code

6.10、re模块

正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行

常用的一些匹配模式:

Python中spam python中spam函数_名称空间_21

Python中spam python中spam函数_序列化

基础类型

# 重复匹配:
#.   ?   *   +  {m,n}  .*  .*?
#1、.:代表除了换行符外的任意一个字符
# print(re.findall('a.c','abc a1c aAc aaaaaca\nc'))
#                                           a.c
# print(re.findall('a.c','abc a1c aAc aaaaaca\nc',re.DOTALL))

#2、?:代表左边那一个字符重复0次或1次
# print(re.findall('ab?','a ab abb abbb abbbb abbbb'))
#                                      ab?

#3、*:代表左边那一个字符出现0次或无穷次
# print(re.findall('ab*','a ab abb abbb abbbb abbbb a1bbbbbbb'))
#                                                   ab*

#4、+ :代表左边那一个字符出现1次或无穷次
# print(re.findall('ab+','a ab abb abbb abbbb abbbb a1bbbbbbb'))
#                                                    ab+

#5、{m,n}:代表左边那一个字符出现m次到n次
# print(re.findall('ab?','a ab abb abbb abbbb abbbb'))
# print(re.findall('ab{0,1}','a ab abb abbb abbbb abbbb'))

# print(re.findall('ab*','a ab abb abbb abbbb abbbb a1bbbbbbb'))
# print(re.findall('ab{0,}','a ab abb abbb abbbb abbbb a1bbbbbbb')) # 出现0次或无穷次

# print(re.findall('ab+','a ab abb abbb abbbb abbbb a1bbbbbbb'))
# print(re.findall('ab{1,}','a ab abb abbb abbbb abbbb a1bbbbbbb'))


# print(re.findall('ab{1,3}','a ab abb abbb abbbb abbbb a1bbbbbbb'))


#6、.*:匹配任意长度,任意的字符=====》贪婪匹配
# print(re.findall('a.*c','ac a123c aaaac a *123)()c asdfasfdsadf'))
#                        a.*c
# 以找到的最后一个c为准

#7、.*?:非贪婪匹配
# print(re.findall('a.*?c','a123c456c'))
# 以找的第一个c为准
# ():分组
# print(re.findall('(alex)_sb','alex_sb asdfsafdafdaalex_sb'))

#                            (alex)_sb
# 以 ‘alex_sb’为标准匹配,最终输出的是括号里面的内容
# print(re.findall(
#     'href="(.*?)"',
#     '<li><a id="blog_nav_sitehome" class="menu" href="">博客园</a></li>')
# )
# <li><a id="blog_nav_sitehome" class="menu" href="">博客园</a></li>
#                                           href=".*?"


# []:匹配一个指定范围内的字符(这一个字符来自于括号内定义的)
# print(re.findall('a[0-9][0-9]c','a1c a+c a2c a9c a11c a-c acc aAc'))

#当-需要被当中普通符号匹配时,只能放到[]的最左边或最 右边,放到中间有特殊意义
# print(re.findall('a[-+*]c','a1c a+c a2c a9c a*c a11c a-c acc aAc'))

# print(re.findall('a[a-zA-Z]c','a1c a+c a2c a9c a*c a11c a-c acc aAc'))


# []内的^代表取反的意思
# print(re.findall('a[^a-zA-Z]c','a c a1c a+c a2c a9c a*c a11c a-c acc aAc'))
# print(re.findall('a[^0-9]c','a c a1c a+c a2c a9c a*c a11c a-c acc aAc'))


# print(re.findall('([a-z]+)_sb','egon alex_sb123123wxxxxxxxxxxxxx_sb,lxx_sb'))
#                                                [a-z]+_sb



# | :或者
# print(re.findall('compan(ies|y)','Too many companies have gone bankrupt, and the next one is my company'))

# (?:):代表取匹配成功的所有内容,而不仅仅只是括号内的内容
# print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt, and the next one is my company'))

# print(re.findall('alex|sb','alex sb sadfsadfasdfegon alex sb egon'))

 

# re模块的其他方法:
# print(re.findall('alex|sb','123123 alex sb sadfsadfasdfegon alex sb egon'))  # 二选一
# print(re.search('alex|sb','123213 alex sb sadfsadfasdfegon alex sb egon').group())   # search:找到一个就停下来
# print(re.search('^alex','123213 alex sb sadfsadfasdfegon alex sb egon'))   #  以alex开头的

# print(re.search('^alex','alex sb sadfsadfasdfegon alex sb egon').group())
# print(re.match('alex','alex sb sadfsadfasdfegon alex sb egon').group())
# match和search中加^的意义相同

# print(re.match('alex','123213 alex sb sadfsadfasdfegon alex sb egon'))


# info='a:b:c:d'
# print(info.split(':'))
# print(re.split(':',info))

# info=r'get :a.txt\3333/rwx'
# print(re.split('[ :\\\/]',info))
# split在re模块中切分可以使用正则表达式

# print('egon is beutifull egon'.replace('egon','EGON',1))

# print(re.sub('(.*?)(egon)(.*?)(egon)(.*?)',r'\1\2\3EGON\5','123 egon is beutifull egon 123'))

#              (123 )(egon)( is beutifull )(egon)( 123)

#\1\2\3EGON\5

# print(re.sub('(lqz)(.*?)(SB)',r'\3\2\1',r'lqz is SB'))
# print(re.sub('([a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)',r'\5\2\3\4\1',r'lqzzzz123+ is SB'))

#(lqzzzz)(123+ )(is)( )(SB)


# pattern=re.compile('alex')
# print(pattern.findall('alex is alex alex'))
# print(pattern.findall('alexasdfsadfsadfasdfasdfasfd is alex alex'))

re补充:

seach和match的区别

1、match()函数只检测RE是不是在string的开始位置匹配

2、search()会扫描整个string查找匹配,会扫描整个字符串并返回第一个成功的匹配

也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none

Python中spam python中spam函数_序列化_23

6.11、hashlib模块

hashlib模块是一种算法,接收传入的内容,经过运算得到一串hash值

# import hashlib
# m=hashlib.md5() 
# m.update('hello'.encode('utf-8'))
# m.update('world'.encode('utf-8'))
# print(m.hexdigest())

在hashlib模块里主要有三个特点:

1、只要传入的内容一样,得到的hash值必然一样====》可以做文件完整性的校验

2、不能由hash值反解成内容====》通过这个方式我们可以将密码做成hash值,不用明文传输

3、只要hash算法不变,无论校验内容有多大,得到hash值得长度是固定的

在平时我们可以通过hashlib模块对编写的程序密码进行密码加密,增加安全性。但是没有任何一种方式是绝对安全的,所以我们还可以对这种加密算法添加自己的key来进一步的加密

# import hashlib
# pwd='123abc'
# m=hashlib.md5()
# m.update('一行白鹭上青天'.encode('utf-8'))  #自己添加的key  
# m.update(pwd.encode('utf-8'))
# print(m.hexdigest())

在python内部还有一个hmac模块,可以直接在内部对我们创建的key和内容进行进一步的处理和加密

1 import hmac
2 h = hmac.new('alvin'.encode('utf8'))
3 h.update('hello'.encode('utf8'))
4 print (h.hexdigest())

6.12、subprocess模块

subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

# import subprocess
# import os
# while True:
#     cmd=input('>>:').strip()
#     if not  cmd:continue
#     os.system(cmd)

# 通过程序来执行dos指令

 

# import subprocess
# obj = subprocess.Popen('dir',
#                        shell=True,
#                        stdout=subprocess.PIPE,
#                        stderr=subprocess.PIPE)
# res1=obj.stdout.read()
# print('正确结果1:',res1)
#
# res2=obj.stdout.read()
# print('正确结果2:',res2)

6.13、configparser模块

# import configparser
#
# config=configparser.ConfigParser()
# config.read('')
# secs=config.sections()
# print(secs)
#
# print(config.options('egon'))  #取出所有的key
#
# print(config.get('egon','age')) #get取出字符串
#
# print(config.getint('egon','age')) #getint,整型

.....

ConfigParser模块在python3中修改为configparser.这个模块定义了一个ConfigParser类,该类的作用是使用配置文件生效,配置文件的格式和windows的INI文件的格式相同该模块的作用 就是使用模块中的RawConfigParser()ConfigParser()、 SafeConfigParser()这三个方法(三者择其一),创建一个对象使用对象的方法对指定的配置文件做增删改查 操作。

配置文件有不同的片段组成和Linux中repo文件中的格式类似:

格式:

[section] 
name=value
或者
name: value
"#" 和";" 表示注释

[DEFAULT] #设置默认的变量值,初始化
[My Section]
foodir: %(dir)s/whatever
dir=frob
long: this value continues
   in the next line

%(dir)s 会被frob代替。默认值会以字典的形式传递给ConfigParser的构造器。section一般存放的哦内置目录下,如果切换到其他的目录需啊哟指定存放位置。

tion: 'mysqld'

作者信息


Python中spam python中spam函数_Python中spam_24