Python3.5学习——模块

模块初识

一、定义

在python中,模块是用来实现某一特定功能的代码集合。其本质上就是以‘.py’结尾的python文件。例如某文件名为test.py,则模块名为test。

二、导入方法

我们在这一节通过举例来向大家简单介绍模块的导入方法。

我们在这里创建一个自定义模块‘module_test’,如下(module_test.py):

name='kobe'
def say_hello():
    print('hello kobe!')

另新建'import_test.py'并在其中导入模块module_test,方法如下:

import module_test
print(module_test.name)
print(module_test.say_hello())

代码执行结果如下:

通过上例,我们可以看出import_test.py通过导入模块module_test,取出了module_test中‘name’变量的值,并且运行了函数say_hello。

若想导入导入多个模块,则可‘import module1,module2...’

>>>import module1, module2,...

若想导入某个模块中某个功能或全部功能

>>>from module import *    #导入module模块中的全部功能
>>>from module import (功能名)  #导入module模块中的某功能

还以上例说明:

from module_test import say_hello as say   #导入module_test模块中的say_hello函数功能,并用‘say’来代替函数名
say()

代码执行结果如下:

通过上述例子我们简单总结一下,即导入模块的本质就是把模块python文件解释一遍。

三、‘包’的定义及导入

‘包’本质就是一个目录(创建好之后会自动其目录下生成一个‘_init_.py’文件)。若包下无其他文件,则导入这个包则本质上即是导入包下的‘_init_.py’文件。

例如,若我们创建一个包‘package_age’,并在其下的‘_init_.py’文件中写入:

print('123456')

再创建一个Python文件‘p_test.py’并导入包‘package_age’:

import package_test

则结果为:

四、非同级目录下的模块导入

若主代码与想要导入的Python文件不在同一级目录下,则不能导入,在导入时会优先在当前路径下去寻找相应的python模块。

例如我们想在目录‘module_test’下的python文件‘main.py’中导入目录‘test4’下的'p_test.py'的python文件(如下图)。

程序实现如下 :

#main.py

from module_kobe import *
logger()
#module_kobe.py

name='kobe bryant'
def say_hello():
    print('hello kobe!')
def logger():
    print('in the module')

代码执行结果如下:

即显示差找不到模块‘module_kobe’。

那么若我们想导入不在同一目录下的模块怎么做呢?这就需要使用‘os’和‘sys’模块来将想要导入模块所在的路径加载到主程序中,还以上述为例,代码编写如下:

import sys,os
print(sys.path)     #以列表的形式打印当前文件所在的路径
print(os.path.abspath(__file__))   #打印当前文件所在的绝对路径
print(os.path.dirname(os.path.abspath(__file__)))   #打印当前文件所在目录
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))    #打印当前文件所在目录的上一级目录
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))    #将当前文件所在目录的上一级目录加载过来

from module_kobe import *
logger()

代码执行结果如下:

可以看到我们实现了导入非同级目录下的python自定义模块功能,其中关于‘os’和‘sys’模块我们在后面会有详细介绍。

 五、模块分类

python中常用的模块主要分为三种:a. 开源模块,b. 自定义模块,c. 标准库(内置模块)。

其中前两种都是程序员自己编写的模块,其中开源模块可以供他人使用,自定义模块一般就是自己使用,上述章节介绍的就是自定义模块。而标准库(内置模块)是python自带的模块,我们写程序时可以直接拿来使用的。

接下来我们简单介绍几个常用的内置模块。

一、时间模块——time与datetime

在python中,通常有这几种方式来表示时间——a. 格式化的时间字符串,b. 时间戳,和表示时间的元组(struct_time)。

首先,格式化的字符串即我们通常意义下的用来表示时间的形式,形如:‘2019-08-29 20:39:40’表示2019年8月29日20时39分40秒。

其次,关于时间戳,我们首先要向大家介绍一下几个概念:

UTC(Coordinated Universal Time,世界协调时间),即格林威治天文时间、世界标准时间,在中国为UTC+8(即比标准时间早八个小时 )。

DST(Daylight Saving Time,夏时制,夏时令):又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。

时间戳(time stamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量,我们可以用‘time.time()’来获取当前的时间戳,如下:

>>>import time
>>>time.time()
1567083047.565318

还有一个是元组(struct_time),获取struct_time的方法如下:

>>>import time
>>> time.localtime()
time.struct_time(tm_year=2019, tm_mon=8, tm_mday=29, tm_hour=20, tm_min=53, tm_sec=2, tm_wday=3, tm_yday=241, tm_isdst=0)

如上,元组struct_time内共有九个元素,依次为:年;月;日;时;分钟;秒;一周的第几天(周一为0,周二为1,以此类推);一年的第几天;是否是夏令时。

 接下来向大家简单介绍一下time模块的几个常用方法:

>>> import time
>>> time.time()     #获取当前时间戳
1567168188.3943985    
>>> time.localtime()     #获取当前当地时间的struct_time元组
time.struct_time(tm_year=2019, tm_mon=8, tm_mday=30, tm_hour=20, tm_min=30, tm_sec=0, tm_wday=4, tm_yday=242, tm_isdst=0)
>>> time.timezone   #获取当地的时区,以秒为单位
-28800
>>> time.altzone     #UTC时间与夏令时的差值
-32400
>>> time.sleep(2)    #睡眠2秒,括号内为可设置的睡眠的秒数
>>> time.gmtime(1567168188.3943985)   #将括号内的时间戳转换成UTC下的struct_time元组格式
time.struct_time(tm_year=2019, tm_mon=8, tm_mday=30, tm_hour=12, tm_min=29, tm_sec=48, tm_wday=4, tm_yday=242, tm_isdst=0)
>>> time.localtime(1567168188.3943985)      #将括号内的时间戳转换成当地的struct_time元组格式(注意与time.gmtime()的差别)
time.struct_time(tm_year=2019, tm_mon=8, tm_mday=30, tm_hour=20, tm_min=29, tm_sec=48, tm_wday=4, tm_yday=242, tm_isdst=0)
>>> time.asctime()
'Fri Aug 30 20:56:58 2019'

若想把struct_time元组的格式转换为格式化的字符串的形式:

>>> x=time.localtime()
>>> time.strftime('%Y-%m-%d %H:%M:%S',x)  #将x以%年-%月-%日 %时:%分钟:%秒的格式输出
'2019-08-30 20:48:52'

同样的,也可以将格式化的字符串装换为struct_time元组格式:

>>> time.strptime('2019-08-30 20:48:52','%Y-%m-%d %H:%M:%S')
time.struct_time(tm_year=2019, tm_mon=8, tm_mday=30, tm_hour=20, tm_min=48, tm_sec=52, tm_wday=4, tm_yday=242, tm_isdst=-1)

若想取出struct_time元组格式时间中的某个元素,如下例:

import time
x=time.localtime()
print(x)
print(x.tm_year)
print('%d' %x.tm_yday)

代码执行结果如下:

 接下来为大家介绍一下datetime模块的使用方法,具体如下:

import datetime
print(datetime.datetime.now())   #获取当前时间
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=3))   #当前时间+3分钟
c_time=datetime.datetime.now()
print(c_time.replace(minute=3,hour=2))  #修改时间,将分钟改为3,小时改为2

代码执行结果如下:

 二、random模块

 random模块即随机数模块,它用来生成随机数。具体介绍如下:

>>> import random
>>> random.random()    #在0到1之间随机取出一个浮点数
0.9835265154729393
>>> random.randint(1,3)  #在[1,3]之间随机取出一个整数(包含1和3)
1
>>> random.randint(1,3)
3
>>> random.randrange(1,3)   #从range(1,3)即[0,1,2]中随机取出一个整数
1
>>> random.choice('hello')    #从字符串‘hello’中随机取出一个字符
'l'
>>> random.choice([1,3,5])   #从列表[1,3,5]中随机取出一个数字
5
>>> random.sample('hello',2)    #从字符串‘hello’中随机取出2个字符
['h', 'l']
>>> random.uniform(1,3)   #在1到3之间随机取出一个浮点数
1.2706200726679393
>>> l=[1,2,3,4,5,6]
>>> random.shuffle(l)   #对l进行重新排序
>>> l
[6, 4, 2, 5, 3, 1]

那么有了上面的铺垫,我们就可以试着写出一个随机输出验证码的代码如下:

'''
设置一个有4位数字的验证码
'''
import random
checkcode=''
for i in range (4):    #将验证码设置成四位
    current=random.randint(0,9)    #从0到9之间随机取出一位整数
    checkcode += str(current)
print(checkcode)

代码执行结果如下:

 

 上例实现了一个比较简单的四位数字的验证码,接下来我们可以尝试写出可以输出含有数字和字母的验证码,且数字和字母的位置数量不固定。

代码实现如下:

'''
设置一个4位的验证码,包含数字和字母
'''
import random
checkcode=''
for i in range (4):   #设置验证码长度为4位
    current=random.randint(0,4)   #从[0,1,2,3]中随机选择一位整数
    if current==i:     #若current==i,则输出子母
        tmp=chr(random.randint(65,90))   #65到90为26个英文字母对应的ASCII码数字
    else:   #若current!=i,则输出数字
        tmp=random.randint(0,9)
    checkcode += str(tmp)
print(checkcode)

代码实现结果如下:

 

 可以看到我们实现了输出包含数字和字母的四位验证码。

三、os模块

os模块即操作系统模块,它提供对操作系统进行调用的接口。

主要调用方式如下:

 import os
>>> os.getcwd()   #查看当前目录
'C:\\Users\\pc'   
>>> os.chdir(r'C:\Program Files')    #切换路径到C:\Program Files
>>> os.getcwd()   #查看当前目录
'C:\\Program Files'
>>> os.curdir   #获取当前目录
'.'       #‘.’代表当前目录
>>> os.pardir    #获取当前目录的父目录
'..'   #'..' 代表上一级目录
>>> os.makedirs(r'D:\a\b\c\d')      #递归的创建目录
>>> os.removedirs(r'D:\a\b\c\d')    #递归地删除目录
>>> os.chdir(r'D:')    #切换路径到D盘
>>> os.mkdir('a')   #生成单级目录
>>> os.rmdir('a')   #删除单级目录
>>> os.listdir('.')   #列出当前目录下的子目录
['.idlerc', '.jssc', '.LSC', '.packettracer', '.PyCharm40', '.QtWebEngineProcess', '3D Objects', 'AppData', 'Application Data', 'Cisco Packet Tracer 6.2sv', 
'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Favorites', 'gsview32.ini', 'IntelGraphicsProfiles', 'Links', 'Local Settings', 'MicrosoftEdgeBackups', 
'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{1b051980-cfce-11e9-b42b-005056c00001}.TM.blf', 
'NTUSER.DAT{1b051980-cfce-11e9-b42b-005056c00001}.TMContainer00000000000000000001.regtrans-ms', 
'NTUSER.DAT{1b051980-cfce-11e9-b42b-005056c00001}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'OneDrive', 'Pictures', 
'PrintHood', 'PycharmProjects', 'q.log', 'Recent', 'Roaming', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'Videos', 'WebpageIcons.db', '「开始」菜单']
>>> os.remove( ) #删除一个文件
>>> os.rename('oldname','newname')    重命名文件,目录
>>> os.stat('D:')   #获取D盘的信息,括号内可为其他文件名或目录名
os.stat_result(st_mode=16895, st_ino=1407374883553285, st_dev=12081982, st_nlink=1, st_uid=0, st_gid=0, st_size=12288, st_atime=1567682975, st_mtime=1567682975, 
st_ctime=1495248147) >>> os.sep #输出操作系统特定的路径分隔符,win为‘\\’,Linux为‘/’ '\\' >>> os.linesep #输出当前平台使用的行终止符,win为‘\r\n’,Linux为‘\n’ '\r\n' >>> os.pathsep #输出用于分隔文件路径的字符串 ';' >>> os.environ #显示环境变量 environ({'COMSPEC': 'C:\\WINDOWS\\system32\\cmd.exe', 'CCPKPATH': 'D:\\CTEX\\CTeX\\fonts\\pk\\modeless\\cct\\dpi$d', 'NUMBER_OF_PROCESSORS': ...... >>> os.name #输出字符串指示当前的使用平台,win为‘nt’,Linux为‘posix’ 'nt' >>> os.system('dir') #运行shell命令 >>> os.path.abspath('d:') #输出括号内目录或文件的规范化的绝对路径 'D:\\' >>> os.path.dirname(path) #返回path所在的目录 >>> os.path.exits(path) #判断path是否存在 >>> os.path.isabs(path) #判断是否是绝对路径(以根目录开头) >>> os.path.isfile(path) #判断是否是文件 >>> os.path.getatime(path) #返回path所指向的文件或目录的最后存取时间 >>> os.path.getmtime(path) #返回path所指向的文件或目录的最后修改时间

四、sys模块

 接下来简单介绍一下sys模块的功能,如下:

>>> import sys
>>> sys.argv     #运行命令行参数list,第一个元素是程序本身路径
['']   
>>> sys.exit()    #退出程序
>>> sys.version    #获取python解释程序的版本信息
'3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)]'

 五、shutil模块

 shutil模块是一个高级的文件、文件夹、压缩包处理模块。

接下来简单介绍一下shutil模块的功能。

首先我们可以用shutil模块来复制文件的内容,具体如下:

import shutil
f1=open('本节笔记',encoding='utf-8')       
f2=open('本节笔记2','w',encoding='utf-8')
shutil.copyfileobj(f1,f2)   #将'本节笔记'内的内容复制到'本节笔记2'中

同样可以起到复制文件功能的还有shutil.copyfile(),具体如下:

import shutil
shutil.copyfile('笔记','笔记2')   #将文件'笔记'的内容复制到'笔记2'中

同时,shutil模块还可以实现压缩文件的功能,介绍如下:

>>>shutil.make_archive(basename,format,root_dir)

其中,basename为压缩包的文件名,也可以是压缩包的路径。format为压缩包的种类,可以是‘zip’,'tar','bztar','gztar'。'root_dir'为要压缩的文件夹路径。

举例如下:

import shutil
import os
print(os.getcwd())   #获取当前路径
shutil.make_archive('shutil_archive_test','zip','D:\python3.5\day5')   #将文件'D:\python3.5\day5'以zip的形式压缩为'shutil_archive_test'

同时,shutil模块还可以其他的一些简单功能,介绍如下:

>>>shutil.copy(src,dst)   #拷贝文件和权限
>>>shutil.copy2(src,dst)   #拷贝文件和权限
>>>shutil.copytree(src,dst)   #递归地拷贝文件
>>>shutil.rmtree(src)   #递归删除目录
>>>shutil.move(src,dst)   #递归地移动文件

 五、xml处理模块

xml是实现不同语言或程序之间进行数据交换的协议,跟jason差不多,但jason使用起来更加简单。不过在jason没诞生之前,大家只能选择用xml,至今仍有许多公司如金融行业的很多系统的接口还主要

是xml。

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

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year updated_by="han">2010</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="han">2013</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year updated_by="han">2013</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>

上述代码描述了三个国家的GDP和邻国等信息,我们可以看到这有点类似于字典。那么我们如何对xml进行处理呢?

下面我们尝试着把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,i.attrib)

#只遍历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) + 2   #year += 2
    node.text = str(new_year)
    node.set("updated_by","kobe")  #添加属性

tree.write("xmltest.xml")

可以看到修改后的xml文件如下:

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year updated_by="kobe">2012</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="kobe">2015</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year updated_by="kobe">2015</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>

同样的,我们也可以自己创建一个xml文件如下:

import xml.etree.ElementTree as ET


new_xml = ET.Element("personinfolist") #根节点
personinfo = ET.SubElement(new_xml,"personinfo",attrib={"enrolled":"yes"})  #创建new_xml的子节点,子节点名为‘name’,子节点属性为"enrolled":"yes"
name = ET.SubElement(personinfo,"name")
name.text='han s'
age = ET.SubElement(personinfo,"age",attrib={"checked":"no"})   #age是name的子节点
sex = ET.SubElement(personinfo,"sex")
age.text = '33'   #赋值
personinfo2 = ET.SubElement(new_xml,"personinfo",attrib={"enrolled":"no"})
name = ET.SubElement(personinfo2,"name")
name.text='duan y'
age = ET.SubElement(personinfo2,"age")
age.text = '19'

et = ET.ElementTree(new_xml) #生成文档对象
et.write("test.xml", encoding="utf-8",xml_declaration=True)   #将创建的xml文件命名为"test.xml"

ET.dump(new_xml) #打印生成的格式

 生成的xml文件如下:

<personinfolist>
    <personinfo enrolled="yes">
        <age checked="no">33</age>
        <sex />
    </personinfo>
    <personinfo enrolled="no">
        <name>duan y</name>
        <age>19</age>
    </personinfo>
</personinfolist>

六、configparser模块

 configparser模块常用来生成和修改常见配置文件。

如常用的配置文件示例如下:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes

[bitbucket.org]
User = hg

[topsecret.server.com]
Port = 50022
ForwardX11 = no

那么如何用configparser模块来创建这样一个配置文件呢?

如下:

import configparser

config = configparser.ConfigParser()

config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9'}

config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'

config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'     # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here

config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
   config.write(configfile)

那么,如果我们想要读取其中的某些内容该如何去做呢?

import configparser

conf=configparser.ConfigParser()
conf.read('example.ini')

print(conf.defaults())   #打印默认
print(conf.sections())  #打印节点

print(conf['bitbucket.org']['User'])

sec=conf.remove_section('bitbucket.org')
conf.write(open('example.cfg','w'))

代码实现结果如下:

 

 七、hashlib模块

hashlib模块用于实现加密相关的操作,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法。

下面的例子实现了对某句话的加密。

import hashlib
m=hashlib.md5()  #md5加密
m.update(b'hello')
print(m.hexdigest())   #十六进制加密

m.update(b'it is me')
print(m.hexdigest())

m2=hashlib.md5()
m2.update(b'helloit is me')
print(m2.hexdigest())

s2=hashlib.sha1()
s2.update(b'helloit is me')
print(s2.hexdigest())

代码运行结果如下:

 

 我们可以看到用SHA1加密算法加密后的结果要比用MD5加密要复杂。

 八、hmac模块

 hmac模块可使内部通过对我们创建key和内容再进行处理后加密。举例如下:

import hmac
h=hmac.new(b'123','长亭外,古道边,芳草碧连天'.encode(encoding='utf-8'))
print(h.hexdigest())

代码执行结果如下:

 

 我们可以看到这实现了加密的效果。

九、re模块

 re模块用做正则表达式,一些常用的正则表达式符号可参见https://www.cnblogs.com/alex3714/articles/5161349.html

我们在这里简单演示演示一下一些常见的匹配语法:

>>> import re
>>> re.match('^han','hanshuo')
<_sre.SRE_Match object; span=(0, 3), match='han'>
>>> re.match('^han','hanshuo').group()
'han'
>>> re.match('.','123ko').group()
'1'
>>> re.search('R[a-zA-Z]+a','chen123RongAhuaRonghua##').group()
'RongAhuaRonghua'
>>> re.search('#.+#','123#hello#').group()
'#hello#'
>>> re.search('(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)','abcd1234daf@').group()
'1234daf'
>>> re.search('(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)','abcd1234daf@').groupdict()
{'id': '1234', 'name': 'daf'}
>>> re.split('[0-9]','abc12de3fr45gh')   #分割
['abc', '', 'de', 'fr', '', 'gh']
>>> re.sub('[0-9]+','1','abc52de3fr45gh',count=2)   #替换,count是替换次数
'abc1de1fr45gh'

 

 

 

 

 


 

posted @ 2019-09-09 20:50  Achilles_Heel  阅读(368)  评论(0编辑  收藏  举报