#------------------------------------datetime------------------------------------#
#处理时间和日期的标准库
#获取当前日期和时间
from datetime import datetime #从模块datetime中导入类datetime
now=datetime.now()
print(now) #2017-07-26 15:58:40.710842
print(type(now)) #<class 'datetime.datetime'>
#获取指定日期和时间
dt=datetime(2015,4,19,12,20) #使用构造函数
print(dt) #2015-04-19 12:20:00
#datetime——>timestamp
#在计算机中,时间实际上是用数字表示的。
#我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为0
#(1970年以前的时间timestamp为负数),
#当前时间就是相对于epoch time的秒数,称为timestamp。
#全球各地的计算机在任意时刻的timestamp都是完全相同的,与时区没有关系
#timestamp是一个浮点数。如果有小数位,小数位表示毫秒数
print(dt.timestamp()) #1429417200.0
print(now.timestamp()) #1501055920.710842
#timestamp——>datetime 指的是当前操作系统设定的时区
t=1429417200.0
print(datetime.fromtimestamp(t)) #2015-04-19 12:20:00
print(datetime.utcfromtimestamp(t)) # UTC标准时区的时间 2015-04-19 04:20:00
#str——>datetime
cday = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')
print(cday) #2015-06-01 18:19:59 字符串'%Y-%m-%d %H:%M:%S'规定了日期和时间部分的格式
#datetime——>str
now = datetime.now()
print(now.strftime('%a, %b %d %H:%M')) #Wed, Jul 26 16:20
#datetime加减
from datetime import timedelta
now=datetime.now()
print(now) #2017-07-26 17:11:02.160141
print(now+timedelta(hours=10)) #2017-07-27 03:11:02.160141
print(now-timedelta(days=1)) #2017-07-25 17:11:02.160141
print(now + timedelta(days=2, hours=12)) #2017-07-29 05:11:02.160141
#本地时间转换为UTC时间
from datetime import timezone
tz_utc_8 = timezone(timedelta(hours=8)) # 创建时区UTC+8:00:在标准时区的基础上加8个小时
now=datetime.now()
print(now) #2017-07-26 17:14:19.777049
dt = now.replace(tzinfo=tz_utc_8) # 强制设置为UTC+8:00
print(dt) #2017-07-26 17:14:19.777049+08:00
#时区转换 先通过utcnow()拿到当前的UTC时间,再转换为任意时区的时间
# 拿到UTC时间,并强制设置时区为UTC+0:00:
utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
print(utc_dt) #2017-07-26 11:07:04.869815+00:00
# astimezone()将转换时区为北京时间:
bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8)))
print(bj_dt) #2017-07-26 19:07:04.869815+08:00
# astimezone()将转换时区为东京时间:
tokyo_dt = utc_dt.astimezone(timezone(timedelta(hours=9)))
print(tokyo_dt) #2017-07-26 20:07:04.869815+09:00
# astimezone()将bj_dt转换时区为东京时间:
tokyo_dt2 = bj_dt.astimezone(timezone(timedelta(hours=9)))
print(tokyo_dt2) #2017-07-26 20:07:04.869815+09:00
#------------------------------------collections------------------------------------#
#collections是Python内建的一个集合模块,提供了许多有用的集合类。
#-------------------namedtuple-----------------
#namedtuple是一个函数,它用来创建一个自定义的tuple对象,
#并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。
#这样一来,我们用namedtuple可以很方便地定义一种数据类型,
#它具备tuple的不变性,又可以根据属性来引用,使用十分方便。
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p=Point(1,2)
print(p,p.x,p.y) #Point(x=1, y=2) 1 2
#-------------------deque-----------------
#使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,
#因为list是线性存储,数据量大的时候,插入和删除效率很低。
#deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
from collections import deque
q = deque(['a', 'b', 'c'])
q.append('x') #尾部添加元素
q.appendleft('y') #头部添加元素
print(q) #deque(['y', 'a', 'b', 'c', 'x'])
q.pop() #尾部删除元素
q.popleft() #头部删除元素
print(q) #deque(['a', 'b', 'c'])
#-------------------defaultdict-----------------
#使用dict时,如果引用的Key不存在,就会抛出KeyError。
#如果希望key不存在时,返回一个默认值,就可以用defaultdict
#默认值是调用函数返回的,而函数在创建defaultdict对象时传入。
#除了在Key不存在时返回默认值,defaultdict的其他行为跟dict是完全一样的。
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
print(dd['key1']) #abc
print(dd['key2']) #N/A
#-------------------OrderedDict-----------------
#使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
#如果要保持Key的顺序,可以用OrderedDict
#OrderedDict是按照插入的顺序,而非key值本身的顺序
from collections import OrderedDict
d = dict([('a', 1), ('b', 2), ('c', 3)])
print(d) #{'b': 2, 'a': 1, 'c': 3} 无序
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(od) #OrderedDict([('a', 1), ('b', 2), ('c', 3)])
odd=OrderedDict()
odd['z']=1
odd['y']=2
odd['x']=3
print(odd) #OrderedDict([('z', 1), ('y', 2), ('x', 3)])
#OrderedDict可以实现一个FIFO的dict,当容量超出限制时,先删除最早添加的Key:
from collections import OrderedDict
class LastUpdatedOrderedDict(OrderedDict):
def __init__(self, capacity):
super().__init__()
#super(LastUpdatedOrderedDict, self).__init__()
self._capacity = capacity
def __setitem__(self, key, value):
containsKey = 1 if key in self else 0 ## 检查dict里是否已经存在要增加的(key,value)中的key
print('self1=',self)
if len(self) - containsKey == self._capacity: #当达到最大容量时,
print('self2=',self)
last = self.popitem(last=False) #就将第一个元素删除(删除最后一个是last=True)
print('remove:', last)
print('self3=',self)
if containsKey: #如果已经包含要添加的key,
print('self4=',self)
del self[key] #就先删除已有的
print('set:', (key, value))
print('self5=',self)
else: #如果不包含
print('add:', (key, value))
print('self6=',self)
OrderedDict.__setitem__(self, key, value) #调用函数,添加新的key
print('self7=',self)
m_od = LastUpdatedOrderedDict(2) #设置容量为2
m_od['a'] = 1
#add: ('a', 1)
#self6= LastUpdatedOrderedDict()
#self7= LastUpdatedOrderedDict([('a', 1)])
m_od['b'] = 2
#add: ('b', 2)
#self6= LastUpdatedOrderedDict([('a', 1)])
#self7= LastUpdatedOrderedDict([('a', 1), ('b', 2)])
m_od['b'] = 2
#self1= LastUpdatedOrderedDict([('a', 1), ('b', 2)])
#self4= LastUpdatedOrderedDict([('a', 1), ('b', 2)])
#set: ('b', 2)
#self5= LastUpdatedOrderedDict([('a', 1)])
#self7= LastUpdatedOrderedDict([('a', 1), ('b', 2)])
m_od['c'] = 3
#self1= LastUpdatedOrderedDict([('a', 1), ('b', 2)])
#self2= LastUpdatedOrderedDict([('a', 1), ('b', 2)])
#remove: ('a', 1)
#self3= LastUpdatedOrderedDict([('b', 2)])
#add: ('c', 3)
#self6= LastUpdatedOrderedDict([('b', 2)])
#self7= LastUpdatedOrderedDict([('b', 2), ('c', 3)])
print(len(m_od)) #2
#-------------------counter-----------------
#Counter是一个简单的计数器,例如,统计字符出现的个数
from collections import Counter
c = Counter()
for ch in 'programming':
c[ch] = c[ch] + 1
print(c)
#Counter({'m': 2, 'r': 2, 'g': 2, 'a': 1, 'n': 1, 'p': 1, 'i': 1, 'o': 1})
#------------------------------------struct------------------------------------#
#在Python中,比方说要把一个32位无符号整数变成字节,也就是4个长度的bytes,你得配合位运算符这么写
n = 10240099
b1 = (n & 0xff000000) >> 24
b2 = (n & 0xff0000) >> 16
b3 = (n & 0xff00) >> 8
b4 = n & 0xff
bs = bytes([b1, b2, b3, b4])
print(bs) #b'\x00\x9c@c'
#Python提供了一个struct模块来解决bytes和其他二进制数据类型的转换。
#struct的pack函数把任意数据类型变成bytes
#第一个参数是处理指令,'>I'的意思是:
#>表示字节顺序是big-endian,也就是网络序,I表示4字节无符号整数。
#后面的参数个数要和处理指令一致。
import struct
print(struct.pack('>I', 10240099)) #b'\x00\x9c@c'
#unpack把bytes变成相应的数据类型
#根据>IH的说明,后面的bytes依次变为I:4字节无符号整数 和H:2字节无符号整数。
print(struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80'))#(4042322160, 32896)
#Windows的位图文件(.bmp)是一种非常简单的文件格式,我们来用struct分析一下
def bmpinfo(file):
f = open(file,'rb')
date = f.read(30) #读入前30个字节
#两个字节:'BM'表示Windows位图,'BA'表示OS/2位图;
#一个4字节整数:表示位图大小;
#一个4字节整数:保留位,始终为0;
#一个4字节整数:实际图像的偏移量;
#一个4字节整数:Header的字节数;
#一个4字节整数:图像宽度;
#一个4字节整数:图像高度;
#一个2字节整数:始终为1;
#一个2字节整数:颜色数。
f.close()
if len(date) == 0:
print('该文件为空')
else:
unpack = struct.unpack('<ccIIIIIIHH', date)
if unpack[0] + unpack[1] ==b'BM':
print('该文件是位图文件')
print('文件大小为%d * %d,文件颜色数位%d' % (unpack[6], unpack[7], unpack[9]))
else:
print('该文件不是位图文件')
#test
bmpinfo('C:/Users/Administrator/Desktop/2.bmp')
#该文件是位图文件 文件大小为258 * 269,文件颜色数位24