2.7. 常见模块
2.7.1. datetime
datetime是Python处理日期和时间的标准库。
datetime表示的时间需要时区信息才能确定一个特定的时间,否则只能视为本地时间。
如果要存储datetime,最佳方法是将其转换为timestamp再存储,因为timestamp的值与时区完全无关。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 获取当前日期
import datetime
now = datetime.datetime.now()
print(now)
print(type(now))
# 获取指定日期和时间
dt = datetime.datetime(2024, 1, 2, 12, 20)
print(dt)
# datetime转换为timestamp
# timestamp = 0 = 1970-1-1 00:00:00 UTC+0:00
dt = datetime.datetime(2024, 1, 2, 12, 20)
print(dt.timestamp())
# timestamp转换为datetime
dt = datetime.datetime.fromtimestamp(dt.timestamp())
print(dt)
print(datetime.utcfromtimestamp(dt)) # UTC时间
# str 2 datetime
import datetime
now =datetime.datetime.strptime("2024-01-01 18:00:00",'%Y-%m-%d %H:%M:%S')
print(now)
# datetime 2 str
now_str =datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(now_str)
# 日期加减
now = datetime.datetime.now()
now + datetime.timedelta(hours=10,days=-1)
# 本地时间转化为utc时间
tz_utc_8 = datetime.timezone(datetime.timedelta(hours=8))
now = datetime.datetime.now()
print(now)
dt = now.replace(tzinfo=tz_utc_8)
print(dt)
# 时区转化
utc_now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
bj_dt = utc_now.astimezone(datetime.timezone(datetime.timedelta(hours=8)))
print(utc_now)
print(bj_dt)
2.7.2. collections
collection是python内建的一个集合模块,提供了许多有用的集合类。
namedtuple
namedtuple是一个函数,它用来创建一个自定义的tuple对象。
from collections import namedtuple
Point = namedtuple('Point',['x','y'])
p = Point(1,2)
print(p.x)
print(p.y)
deque
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈。 list不适合频繁插入删除。
from collections import deque
q = deque(['a','b','c'])
q.append('d')
q.appendleft('y')
print(q)
defaultdict
如果希望key不存在时,返回一个默认值,就可以用defaultdict。
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
print(dd["k1"])
OrderedDict
如果要保持Key的顺序,可以用OrderedDict。
from collections import OrderedDict
d = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(d)
ChainMap
ChainMap是可以把一组dict串起来组成的逻辑dict,会优先查找内部的dict,依次查找外部。
from collections import ChainMap
import os
d1 = {
'color': 'red',
'user': 'zhaojiedi'
}
d2 = {
'color': 'blue'
}
d3 = {
'age': 1,
}
combined = ChainMap(d1,d2,d3)
print(combined['color'])
print(combined['age'])
Counter
counter是一个简单的计数器。
from collections import Counter
c =Counter()
c.update('hello')
print(c)
2.7.3. argparser
argparse是用于解析命令行参数的。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
def main():
p = argparse.ArgumentParser(
prog='backup',
description='backup db',
epilog='copyright ,2023'
)
p.add_argument('outfile')
p.add_argument('--host',default='localhost')
p.add_argument('--port',default=3306,type=int)
p.add_argument('-u', '--user', required=True)
p.add_argument('-p', '--password', required=True)
p.add_argument('--database', required=True)
p.add_argument('-gz', '--gzcompress', action='store_true', required=False, help='Compress backup files by gz.')
args = p.parse_args()
print(args)
if __name__ == '__main__':
# (venv) ➜ My_Study_Python git:(master) ✗ python3 ./source/code/14.03.argparse.py -uroot -poracle --database d1 -gz a.txt
# Namespace(outfile='a.txt', host='localhost', port=3306, user='root', password='oracle', database='d1', gzcompress=True)
main()
2.7.4. base64
base64是一种64个字符来表示任意二进制数据的方法。
base64是64个字符,包含26个字母的大写和小写,数字10个,另外包含’+’ 和 ‘/’ 。
在urlsafe中,将’+’变成’-’,将’/’变成’_’。
In [5]: base64.b64encode(b'i\xb7\x1d\xfb\xef\xff')
Out[5]: b'abcd++//'
In [6]: base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff')
Out[6]: b'abcd--__'
2.7.5. struct
todo
2.7.6. hashlib
可以通过hashlib计算摘要信息。
In [7]: import hashlib
In [8]: md5 = hashlib.md5()
In [9]: md5.update('zhaojiedi'.encode('utf-8'))
In [10]: md5.hexdigest()
Out[10]: 'efb605a4a365423301d33afec4138813'
2.7.7. hmac
In [1]: import hmac
In [2]: message=b'abc'
In [3]: key=b'secret'
In [4]: h = hmac.new(key,message,digestmod='md5')
In [5]: h.hexdigest()
Out[5]: 'd9bf7c3a63eae7031c4e6d7c9b78ba93'
2.7.8. itertools
# 三个字母循环的。
cs = itertools.cycle('ABC')
# 重复一个元素多次
ns = itertools.repeat('A', 3)
# 提前特定个数
itertools.takewhile(lambda x: x <= 10, natuals)
# 整合一个大的
for c in itertools.chain('ABC', 'XYZ'):
# groupby()把迭代器中相邻的重复元素挑出来放在一起:
for key, group in itertools.groupby('AAABBBCCAAA'):
print(key, list(group))
2.7.9. contextlib
实现上下文管理是通过__enter__和__exit__这两个方法实现的。
编写__enter__和__exit__仍然很繁琐,因此Python的标准库contextlib提供了更简单的写法
如果一个对象没有实现上下文,我们就不能把它用于with语句。这个时候,可以用closing()来把该对象变为上下文对象
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Query(object):
def __init__(self, name):
self.name = name
def __enter__(self):
print('start')
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type:
print('Error')
else:
print('End')
def query(self):
print('Query info about %s...' % self.name)
with Query("abc") as f:
f.query()
from contextlib import contextmanager
class QueryV2(object):
def __init__(self, name):
self.name = name
def query(self):
print('Query info about %s...' % self.name)
@contextmanager
def create_query(name):
print('Begin')
q = QueryV2(name)
yield q
print('End')
with create_query("abc") as q:
q.query()
@contextmanager
def tag(name):
print("<%s>" % name)
yield
print("</%s>" % name)
with tag("h1"):
print("hello")
print("world")
from contextlib import closing
from urllib.request import urlopen
with closing(urlopen('https://www.python.org')) as page:
for line in page:
print(line)
@contextmanager
def closing(thing):
try:
yield thing
finally:
thing.close()
2.7.10. request
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from urllib import request
with request.urlopen('https://api.douban.com/v2/book/2129650') as f:
data = f.read()
print(f.status)
print(data)
# todo post