常用内置模块


1 time

在python中,通常有以下几种方式来表示时间

  • 时间戳,如time.time()
  • 格式化的时间字符串,如'17/01/2017 10:17:00'
  • 元组(struct_time),如gmtime、localtime等等。

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

struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)

把从1970年开始到现在的所有时间转换成秒数,即时间戳

import time
print(time.time())      # 1562226752.302741

将时间戳(秒数)转换成UTC时区的元组形式
结构化UTC世界标准时间

import time
print(time.gmtime())    # time.struct_time(tm_year=2019, tm_mon=7, tm_mday=4, tm_hour=7, tm_min=54, tm_sec=11, tm_wday=3, tm_yday=185, tm_isdst=0)

将时间戳转换成当地时区的元组形式

import time
print(time.localtime()) # time.struct_time(tm_year=2019, tm_mon=7, tm_mday=4, tm_hour=15, tm_min=55, tm_sec=29, tm_wday=3, tm_yday=185, tm_isdst=0)

这种元组形式的时间可以通过其内部的方法取得需要的时间元素。例:

import time

x = time.localtime()

print(x.tm_year)   # 可以取得当前是哪一年
print(x.tm_mon)    # 可以取得当前是哪一月
print(x.tm_mday)   # 可以取得当前是哪一天

睡眠s秒

import time
time.sleep(5)       # 睡眠5秒

将元组(tuple)形式的时间转换成时间戳

import time
t = time.mktime(time.localtime())
print(t)    # 1562227302.0

将元组形式的时间转换成格式化的时间字符串(用数字方式显示)
time.strftime(format[, tuple])
将元组形式的时间转换成格式化的时间字符串(用数字方式显示),若不指定tuple则转换当前的localtime

import time
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)

将格式化的时间字符串转换成元组形式的时间

import time
t = time.strptime('2018-08-09 16:37:06', '%Y-%m-%d %X')
print(t)

将元组形式的时间转换成格式化的时间字符串(用英文方式显示)
time.asctime([tuple])
若不指定tuple则转换当前的localtime

import time
t = time.asctime()
print(t)

t1 = time.asctime(time.gmtime())
print(t1)

将时间戳转换成格式化的时间字符串(用英文方式显示)
time.ctime([seconds])
若不指定时间戳则转换当前的时间戳

import time
t = time.ctime()
print(t)

t1 = time.ctime(100000)
print(t1)

2 datetime

取得当前的日期与时间

import datetime
print(datetime.datetime.now())

取得三天后的当前时间

import datetime
today = datetime.datetime.now()     # 获取当前时间
offset = datetime.timedelta(days=3)     # 在今天的基础上向后偏移3天
re_date = (today + offset).strftime('%Y-%m-%d')     # 获取三天后的当前时间
print(re_date)

取得三天前的当前时间

import datetime
today = datetime.datetime.now()     # 获取当前时间
offset = datetime.timedelta(days=-3)     # 在今天的基础上向前偏移3天
re_date = (today + offset).strftime('%Y-%m-%d')     # 获取三天前的当前时间
print(re_date)

取得三小时前的当前时间

import datetime
today = datetime.datetime.now()     # 获取当前时间
offset = datetime.timedelta(hours=-3)     # 在当前时间的基础上向前偏移3小时
re_date = (today + offset).strftime('%Y-%m-%d %H:%M:%S')     # 获取3小时前的当前时间
print(re_date)

取得三小时后的当前时间

import datetime
today = datetime.datetime.now()     # 获取当前时间
offset = datetime.timedelta(hours=3)     # 在当前时间的基础上向后偏移3小时
re_date = (today + offset).strftime('%Y-%m-%d %H:%M:%S')     # 获取3小时后的当前时间
print(re_date)

时间替换

import datetime
print(datetime.datetime.now().replace(minute=10,hour=10))

3 random(随机数)

取得0-1之间的浮点随机数

import random
print(random.random())

取得1-10之间的浮点随机数,1和10可以任意指定

import random
print(random.uniform(1,10))

取得1-3之间的任意随机数,包括1和3,这里的1和3可以任意指定

import random
print(random.randint(1,3))

取得1-10之间的任意随机数,不包括10,这里的1和10可以任意指定

import random
print(random.randrange(1,10))

从序列sequence中随机取一个元素

import random
print(random.choice([1,2,3,4,5,6,7,8,9,10]))

每次从序列sequence中随机取count个元素

import random
print(random.sample([1,2,3,4,5,6,7,8,9,10],3))

洗牌,将一个序列的顺序打乱

import random
a = [1,2,3,4,5,6,7,8,9,10]
print(a)
print('------------------------------')
random.shuffle(a)
print(a)

验证码

import random

def v_code():

    code = ''
    for i in range(6):

        num=random.randint(0,9)
        alf=chr(random.randint(65,90))
        add=random.choice([num,alf])
        code += str(add)
    return code

print(v_code())

4 os

OS模块提供对操作系统进行调用的接口
获取当前工作目录

import os
print(os.getcwd())

切换目录

import os
print(os.getcwd())      # 打印当前目录
os.chdir('/etc')        # 切换目录至/etc
print(os.getcwd())      # 打印当前目录

返回当前目录

import os
print(os.curdir)        # 打印表示当前目录的 .

返回当前目录的父目录

import os
print(os.pardir)        # 打印表示父目录的 ..

递归创建目录
os.makedirs(name, mode=511, exist_ok=False)

import os
os.makedirs(r'/tmp/a/b/c/d')

删除目录
若目录为空则删除,并递归到上一级目录,若还是为空则再删除,依此类推

import os
os.removedirs(r'/tmp/a')    # 报错,因为a目录不为空

os.removedirs(r'/tmp/a/b/c/d')

创建单级目录,若父目录不存在则抛出异常
os.mkdir(path, mode=511, *, dir_fd=None)

import os
os.mkdir(r'/tmp/a/b/c/d')   # 报错,因为父级目录不存在

os.mkdir(r'/tmp/a')

删除单级空目录,若目录不为空则抛出异常
os.rmdir(path, *, dir_fd=None)

import os
os.makedirs(r'/tmp/a/b/c/d')    # 创建多级目录
os.rmdir(r'/tmp/a')         # 报错,因为a目录非空

列出某路径下的所有文件,包括文件和目录
os.listdir(path=None)

import os
print(os.listdir(r'/tmp/'))

删除一个文件

import os
os.remove(r'/root/abc')     # 此处只能删除文件

重命名文件/目录

import os
os.rename('/root/anaconda-ks.cfg','/root/haha')

获取文件/目录信息

import os
print(os.stat('/root/haha'))

输出操作系统特定的路径分隔符
输出操作系统特定的路径分隔符,win下为'\',linux下为'/'

import os
print(os.sep)

输出当前平台使用的行终止符
输出当前平台使用的行终止符,win下为'\r\n',linux下为'\n'

import os
print(os.linesep)       # 在交互式模式下才能看到效果

输出用于分割文件路径的字符串
输出用于分割文件路径的字符串,存放多个路径的时候区分不同路径时用的分隔符

import os
print(os.pathsep)       # 打印用于分隔多个路径的分隔符,例如PATH变量中的路径

输出字符串指示当前使用平台
输出字符串指示当前使用平台。win-->'nt',linux-->'posix'

import os
print(os.name)

运行shell命令
运行shell命令,直接显示结果,返回值为命令执行的状态码

import os
a = os.system('ls /tmp')
print('##########################################')
print(a)

运行shell命令,命令结果作为返回值返回并打印至屏幕

import os
print(os.popen('ls /tmp'))

for i in os.popen('ls /tmp'):       # 用for循环一个个把内容打印出来
    print(i)

以图形化方式打开一个程序,只适用于windows

import os
os.startfile(r'C:\Windows\System32\notepad.exe')    # 打开记事本

获取系统环境变量

import os
print(os.environ)
# print(os.environ['PATH'])

5 os.path

返回指定文件的绝对路径

import os
print(os.path.abspath('haha'))      # 返回当前目录下名字为haha的文件或目录的绝对路径

返回将指定路径分割成以目录和文件名作为元素的2元素元组

import os
print(os.path.split('/root/abc'))
print(os.path.split('/root/abc/'))

返回指定路径的目录部分。其实就是os.path.split(path)的第一个元素

import os
print(os.path.dirname('/root/abc'))
print(os.path.dirname('/root/abc/'))

返回指定路径最后的文件名
返回指定路径最后的文件名。如果路径以/或\结尾,那么就会返回空值。其实就是os.path.split(path)的第二个元素

import os
print(os.path.basename('/root/abc'))
print(os.path.basename('/root/abc/'))

判断指定路径是否存在
判断指定路径是否存在,存在返回True,否则返回False

import os
print(os.path.exists('/root/abc'))

判断指定路径是不是一个绝对路径

import os
print(os.path.isabs('root/abc'))    # False
print(os.path.isabs('/root/abc'))   # True

判断指定路径是不是一个文件

import os
os.path.isfile('/root/haha')

判断指定路径是不是一个目录

import os
os.path.isdir('/root/hehe')

将多个路径组合后返回,第一个绝对路径之前的参数将被忽略

import os
print(os.path.join('root','abc','def'))
print(os.path.join('/root','abc','def'))
print(os.path.join('/root','abc','def/'))

返回指定路径所指向的文件或目录的最后访问时间的时间戳

import os
print(os.path.getatime('/root/haha'))

返回指定路径所指向的文件或目录的最后内容修改时间的时间戳

import os
print(os.path.getmtime('/root/haha'))

6 sys

sys.argv
命令行参数列表,第一个元素是程序本身路径

[root@localhost ~]# vim test.py
import sys
print('脚本名:',sys.argv[0])
print('参数1:',sys.argv[1])
print('参数2:',sys.argv[2])

[root@localhost ~]# python3.7 test.py abc def
脚本名: test.py
参数1: abc
参数2: def

sys.exit(n)
退出程序,正常退出时exit(0),n可以是数字也可以是字符串

[root@localhost ~]# vim test.py
import sys
sys.exit('haha')
print('能看到我吗?')

[root@localhost ~]# python3.7 test.py
haha

sys.version
获取python解释程序的版本信息

import sys
print(sys.version)

返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值

import sys
print(sys.path)

返回操作系统平台名称

import sys
print(sys.platform)

进度条案例

import sys,time
for i in range(10):
    sys.stdout.write('#')       # 在屏幕上输出#号
    time.sleep(1)
    sys.stdout.flush()          # 刷新写缓存

7 hashlib

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

import hashlib

m = hashlib.md5()  # m=hashlib.sha256()

m.update('hello'.encode('utf8'))
print(m.hexdigest())  # 5d41402abc4b2a76b9719d911017c592

m.update('wangqing'.encode('utf8'))

print(m.hexdigest())  # 5315b54a32ce60bab5aa1e72bab09133

m2 = hashlib.md5()
m2.update('hellowangqing'.encode('utf8'))
print(m2.hexdigest())  # 5315b54a32ce60bab5aa1e72bab09133

以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

import hashlib

# ######## 256 ########

hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
hash.update('wangqing'.encode('utf8'))
print(hash.hexdigest())  # f00ac2a3bcd6bc8b7eafb2e66c04c799dc9008222b27299e42bf895c8be86cdb

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

import hmac

h = hmac.new('wangqing'.encode('utf8'))
h.update('hello'.encode('utf8'))
print(h.hexdigest())    # 9e5926557f4687c5731dbe9775be6cf1

8 shutil

shutil模块专门用来copy文件,可以压缩包

拷贝文件

import shutil
shutil.copy('wangqing','taoist')

递归拷贝文件(拷贝目录,包括其内的文件)
shutil.copytree(src,dst,symlink=False,ignore=None)

import shutil
shutil.copytree('runtime','haha')

递归删除目录,只能删除目录(包括其内的文件)
shutil.rmtree(path [, ignore_errors [, onerror]])

import shutil
shutil.rmtree('haha')

递归的移动文件,亦可用于重命名,可用于文件和目录

import shutil
shutil.move('runtime','haha')

创建压缩包并返回文件路径,例如:zip、tar
shutil.make_archive(base_name,format,...)

base_name:

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

format:压缩包种类。'zip'、'tar'、'bztar'、'gztar'

root_dir:要压缩的目录路径(默认当前目录)
owner:用户。默认当前用户
group:组。默认当前组

import shutil

# 对当前目录进行bz2格式压缩,压缩后文件名为abc.tar.bz2
shutil.make_archive('abc','bztar')

# 对haha目录进行bz2格式压缩,压缩后文件名为haha.tar.bz2  
shutil.make_archive('haha','bztar',root_dir='haha')

9 json & pickle

用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

import json

x = "[true,false,0,1,null]"
# print(x)
# print(type(x))
#
# print(eval(x))
# print(type(eval(x)))
#
# print(eval('1+2*5'))

print(json.loads(x))

json和pickle是用于序列化的两个重要模块。那么什么是序列化呢
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

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

9.1 json

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

JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

json类型 python类型
{} dict
[] list
“String" str
1234.56 int或float
true/false True/False
null None
#----------------------------序列化
import json
 
dic = {'name':'wangqing','age':25,'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)

注意事项:
json不认可单引号,数据必须以双引号引起来

import json
# dct="{'1':111}"        # json 不认单引号
# dct=str({"1":111})     # 报错,因为生成的数据还是单引号:{'one': 1}

dct = '{"1":"111"}'
print(json.loads(dct))      

无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不是非要dumps的数据才能loads

9.2 pickle

##----------------------------序列化
import pickle

dic = {'name': 'wangqing', 'age': 25, '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'])

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

json与pickle两者均提供了四个功能:dumps、dump、loads、load

  • dumps和loads直接在内存中操作,不对文件进行操作
  • dump和load会对文件进行操作:写入和读取

10 shelve

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

import shelve

f = shelve.open(r'wangqing.txt')

f['stu1_info'] = {'name':'tom','age':'18'}
f['stu2_info'] = {'name':'jerry','age':'20'}
f['school_info'] = {'website':'wangqing.com','city':'wuhan'}

# f.close()

print(f.get('stu1_info')['age'])

11 xml

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


View Code

import xml.etree.ElementTree as ET

tree = ET.parse("data.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)
# ---------------------------------------

import xml.etree.ElementTree as ET

tree = ET.parse("data.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("data.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文档:


创建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")
age.text = '33'
name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age = ET.SubElement(name2, "age")
age.text = '19'

et = ET.ElementTree(new_xml)  # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True)

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

12 configparser

configparser模块常用于生成或修改常见配置文档。

先看一个好多软件的常见文档格式

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
  
[wangqing.com]
User = root
  
[www.wangqing.com]
Port = 50022
ForwardX11 = no

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

import configparser

config = configparser.ConfigParser()

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

config['wangqing.com'] = {}
config['wangqing.com']['User'] = 'root'

config['www.wangqing.com'] = {}
www = config['www.wangqing.com']
www['Port'] = '50022'
www['ForwardX11'] = 'no'

config['DEFAULT']['ForwardX11'] = 'yes'

with open('example.ini','w') as configfile:
    config.write(configfile)

增删改查

import configparser

config = configparser.ConfigParser()

#---------------------------------------------查
print(config.sections())   # []

config.read('example.ini')

print(config.sections())   # ['wangqing.com', 'www.wangqing.com']

print('runtime.com' in config) # False

print(config['wangqing.com']['User']) # root

print(config['DEFAULT']['Compression']) # yes

print(config['www.wangqing.com']['ForwardX11'])  # no


for key in config['wangqing.com']:
    print(key)

# 输出如下:
    # user
    # serveraliveinterval
    # compression
    # compressionlevel
    # forwardx11


print(config.options('wangqing.com'))   # ['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
print(config.items('wangqing.com'))    # [('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'root')]

print(config.get('wangqing.com','compression')) # yes


#---------------------------------------------删,改,增(config.write(open('i.cfg', "w")))


config.add_section('mysql')

config.remove_section('www.wangqing.com')
config.remove_option('wangqing.com','user')

config.set('wangqing.com','KO1','10000')

config.write(open('i.cfg', "w"))