常见内置模块
datetime是Python处理日期和时间的标准库。
datetime
是模块,datetime
模块还包含一个datetime
类,通过from datetime import datetime
导入的才是datetime
这个类
datetime
from datetime import datetime
now=datetime.now() # 获取当前时间
print(now) # 2018-08-03 15:06:09.944095
print(type(now)) # <class 'datetime.datetime'>
date1=datetime(2015, 10, 8, 1, 11) # 创建指定日期时间
print(date1) # 2015-10-08 01:11:00
# 在计算机中 时间使用数字(时间戳)表示的
timestamp=date1.timestamp() #将datetime转为时间戳
print(timestamp) # 1444237860.0
date2=datetime.fromtimestamp(timestamp) # 将时间戳转为本地时间
date3=datetime.utcfromtimestamp(timestamp) #将时间转为UTC时间
print(date2) # 2015-10-08 01:11:00
print(date3) # 2015-10-07 17:11:00
# str转date
date4=datetime.strptime("2015-6-1 18:19:59", "%Y-%m-%d %H:%M:%S")
print(date4) # 2015-06-01 18:19:59
# date转str
str1=date4.strftime("%a, %b %d %H:%M")
print(str1) # Mon, Jun 01 18:19
# 时间增减
from datetime import datetime, timedelta
now1=datetime.now()
newdate1=now1+timedelta(hours=12) # 增加12小时的时间
newdate2=now1-timedelta(days=2, minutes=50)
print(newdate1) # 2018-08-04 04:09:26.450345
print(newdate2) # 2018-08-01 16:25:14.299462
# datetime 有一个时区属性tzinfo 但是默认为 None 因此无法区分时间的时区 我们可以给其设置一个时区,帮助区分是哪个时区的时间
from datetime import datetime, timedelta, timezone
tz_utc_8=timezone(timedelta(hours=8))
print(tz_utc_8) # UTC+08:00
print(now) # 2018-08-03 17:26:29.846861
date_utc_8=now.replace(tzinfo=tz_utc_8)
print(date_utc_8) # 2018-08-03 17:26:29.846861+08:00
# 获取当前的utc时间 并且加上utc时区信息
utc_dt=datetime.utcnow().replace(tzinfo=timezone.utc)
print(utc_dt) # 2018-08-03 09:30:57.959514+00:00
print(datetime.utcnow()) # 2018-08-03 09:30:57.959525
print(timezone.utc) # UTC
# 将utc时间转为北京时区时间
bj_dt=utc_dt.astimezone(timezone(timedelta(hours=8)))
print(bj_dt) # 2018-08-03 17:39:22.703278+08:00
datetime
有一个时区属性tzinfo
但是默认为None
因此无法区分时间的时区 我们可以给其设置一个时区,帮助区分是哪个时区的时间任何带时区新的
date
都可以转换时间要存储
datetime
,最佳方法是将其转换为timestamp
再存储,因为timestamp
的值与时区完全无关
collections
内置的一个集合模块 提供了许多有用的集合类
namedtuple
是一个用来创建自定义的tuple
对象,规定了元素个数,可以用属性而不是索引来引用tuple
中的元素
from collections import namedtuple
Point=namedtuple("point", ["x", "y"])
p1=Point(2, 3)
print("坐标为 %s %s" % (p1.x, p1.y)) # 坐标为 2 3
isinstance(p1, Point) #True
deque
为了弥补list
线性存储插入和删除元素慢,deque
是双向列表,适合于队列和栈,除了实现了list的append()
和pop()
外,还支持appendleft()
和popleft()
,可以方便的向头部添加或删除数据
from collections import deque
q1=deque(["1", "2", "3"])
q1.append("x")
q1.appendleft("y")
print(q1) # deque(['y', '1', '2', '3', 'x'])
defaultdict
当dict
中引用的key不存在时,返回默认值
默认值是调用函数返回的,而函数在创建defaultdict对象时传入。
from collections import defaultdict
dd1=defaultdict(lambda:"defaultValue")
dd1["key1"]="abc"
print(dd1["key1"]) # abc
print(dd1["key2"]) # defaultValue
OrderedDict
dict
是无序的 如果要保持key
顺序 可以使用OrderedDict
,OrderedDict
会按照插入的顺序排除
Counter
简单的计数器,也是dict
的一个子类
from collections import Counter
c1=OrderedDict()
for char in "programming":
c1[char]=c1[char]+1
print(c1)
# Counter({'r': 2, 'g': 2, 'm': 2, 'p': 1, 'o': 1, 'a': 1, 'i': 1, 'n': 1})
base64
base64
将3字节的数据编码为4字节,长度增加了33%,如果不足的话会用0x00
在末尾补全,然后在末尾加同样数量的=
标识,这样解码的时候会自动去掉
Python
内置的有base64
编码方法
由于标准的base64编码后可能出现字符+和/ 不能在url中作为参数,因此可以受用url safe
的base64,将+和/换位-和_
import base64
b64encodestr1=base64.b64encode(b"binary\x00string")
print(b64encodestr1) # b'YmluYXJ5AHN0cmluZw=='
b64decodestr2=base64.b64decode(b64encodestr1)
print(b64decodestr2) # b'binary\x00string'
#urlsafe_b64encode
base64encodestr2=base64.b64encode(b"i\xb7\x1d\xfb\xef\xff")
print(base64encodestr2) # b'abcd++//'
base64urlsafeencode=base64.urlsafe_b64encode(b"i\xb7\x1d\xfb\xef\xff")
print(base64urlsafeencode) # b'abcd--__'
struct
python内置了struct
模块来解决bytes
和其它二进制数据类型的转换
import struct
struct1=struct.pack(">I", 10240099)
print(struct1) # b'\x00\x9c@c'
struct2=struct.unpack(">IH", b"\xf0\xf0\xf0\xf0\x80\x80")
print(struct2) # (4042322160, 32896)
参数中>
表示网络序的大端, I:4字节无符号整数 H:2字节无符号整数
hashlib
python提供摘要算法,包括MD5 SHA1等
MD5摘要
import hashlib
#md5()可以不加参数 然后update()内容 如果内容过多也可以多次 update
md5=hashlib.md5("到付奥佛八奥保护管安排表佛八".encode("utf-8"))
md5.update("dddd".encode("utf-8"))
print(md5.hexdigest()) # a459918710ca186970b2ed69cedee466
SHA1摘要
import hashlib
sha1 = hashlib.sha1()
sha1.update('how to use sha1 in '.encode('utf-8'))
sha1.update('python hashlib?'.encode('utf-8'))
print(sha1.hexdigest())
hmac
只是简单的摘要哈希的话,有被黑客破译的风险,这时候我们经常需要做加盐处理
import hmac
message=b"Hello, world"
key=b"secert"
h=hmac.new(key, message, digestmod="MD5")
print(h.hexdigest()) # 4f05d03996e3c5c96ccde51100246253
itertools
itertools
提供了有用于操作迭代对象的函数
import itertools
# 创建几个 无限重复序列
natuals=itertools.count(1) # 1 2 3 4 ....
cs=itertools.cycle("ABc") # A B C A B C ...
ns=itertools.repeat("A") # A A A A A A ...
# 可以加第二个参数 指定重复次数
ns=itertools.repeat("A", 3) # A A A
takewhile()
对于itertools无限序列,通常用takewhile()
截取有用序列
natuals1=itertools.count(1)
result1=itertools.takewhile(lambda x : x<4, natuals1)
print(list(result1)) # [1, 2, 3]
chain()
chain()可以把一组迭代对象串联起来,形成一个更大的迭代器
for c in itertools.chain('ABC', 'XYZ'):
print(c)
# 迭代效果:'A' 'B' 'C' 'X' 'Y' 'Z'
groupby()
groupby()把迭代器中相邻的重复元素挑出来放在一起:
for key, group in itertools.groupby('AAABBBCCAAA'):
print(key, list(group))
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
# 挑选规则实际上是通过函数完成的
for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
print(key, list(group))
A ['A', 'a', 'a']
B ['B', 'B', 'b']
C ['c', 'C']
A ['A', 'A', 'a']
contextlib
对于读写文件我们已经使用过with()
语句 其实只要实现了上下文管理都可以使用with语句
urllib
urllib
内建模块提供了操作url功能
get
POST
XML
操作XML通常有两种方法:DOM和SAX
DOM会把整个XML读入内存,可以解析遍历树的任何节点,缺点是占用内存大,解析慢
SAX是流模式,边读边解析,占用内存小,解析快,缺点是需要自己处理事件
通常选择SAX 因为DOM太耗内存
from xml.parsers.expat import ParserCreate
class DefaultSaxHandler(object):
def start_element(self, name, attrs):
print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))
def end_element(self, name):
print('sax:end_element: %s' % name)
def char_data(self, text):
print('sax:char_data: %s' % text)
xml = r'''<?xml version="1.0"?>
<ol>
<li><a href="/python">Python</a></li>
<li><a href="/ruby">Ruby</a></li>
</ol>
'''
handler = DefaultSaxHandler()
parser = ParserCreate()
parser.StartElementHandler = handler.start_element
parser.EndElementHandler = handler.end_element
parser.CharacterDataHandler = handler.char_data
parser.Parse(xml)
需要注意的是读取一大段字符串时,CharacterDataHandler可能被多次调用,所以需要自己保存起来,在EndElementHandler里面再合并。
因为XML解析太复杂 建议你改用JSON
HTMLParser
当需要解析HTML内容时,因为HTML的语法没有XML那么严格,所以不能用标准的DOM
或SAX
解析,python提供了HTMLParser
来解析HTML
from html.parser import HTMLParser
from html.entities import name2codepoint
class MyHTMLParser(HTMLParser):
def handle_starttag(self, tag, attrs):
print('<%s>' % tag)
def handle_endtag(self, tag):
print('</%s>' % tag)
def handle_startendtag(self, tag, attrs):
print('<%s/>' % tag)
def handle_data(self, data):
print(data)
def handle_comment(self, data):
print('<!--', data, '-->')
def handle_entityref(self, name):
print('&%s;' % name)
def handle_charref(self, name):
print('&#%s;' % name)
parser = MyHTMLParser()
parser.feed('''<html>
<head></head>
<body>
<!-- test html parser -->
<p>Some <a href=\"#\">html</a> HTML tutorial...<br>END</p>
</body></html>''')
feed()
方法可以多次调用,也就是不一定一次把整个HTML字符串都塞进去,可以一部分一部分塞进去。特殊字符有两种,一种是英文表示的
 
;,一种是数字表示的Ӓ
;,这两种字符都可以通过Parser解析出来。