time模块
时间表示方式
- 时间戳timestamp:表示的是从1970年1月1日00:00:00开始按秒计算的偏移量
- UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8。DST(Daylight Saving Time)即夏令时
- 元组(struct_time):由9个元素组成
struct_time元组
索引 | 属性 | 值 |
---|---|---|
0 | tm_year | 2000 |
1 | tm_mon | 1-12 |
2 | tm_mday | 1-31 |
3 | tm_hour | 0-23 |
4 | tm_min | 0-59 |
5 | tm_sec | 0-61 |
6 | tm_wday | 0-6(0表示周一) |
7 | tm_yday(一年中的第几天) | 1-366 |
8 | tm_isdst(是否为dst时间) | 默认为-1 |
time模块方法
time.localtime([secs])
:将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准time.gmtime([secs])
:和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_timetime.time()
:返回当前时间的时间戳time.mktime(t)
:将一个struct_time转化为时间戳time.sleep(secs)
:线程推迟指定的时间运行。单位为秒time.asctime([t])
:把一个表示时间的元组或者struct_time表示为这种形式:‘Sun Jun 20 23:21:05 1993’。如果没有参数,将会将time.localtime()作为参数传入time.ctime([secs])
:把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式time.strftime(format[, t])
:把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()time.strptime(string[, format])
:把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作
时间样式
格式 | 含义 | 格式 | 含义 |
---|---|---|---|
%a | 本地简化星期名称 | %m | 月份(01 - 12) |
%A | 本地完整星期名称 | %M | 分钟数(00 - 59) |
%b | 本地简化月份名称 | %p | 本地am或者pm的相应符 |
%B | 本地完整月份名称 | %S | 秒(01- 61) |
%c | 本地相应的日期和时间 | %U | 一年中的星期数(0– 53,星期日是一个星期的开始) |
%d | 一个月中的第几天(01- 31) | %w | 一个星期中的第几天(0- 6,0是星期天) |
%H | 一天中的第几个小时(24小时制,00- 23) | %x | 本地相应日期 |
%I | 第几个小时(12小时制,01-12) | %X | 本地相应时间 |
%j | 一年中的第几天(001 - 366) | %y | 去掉世纪的年份(00 - 99) |
%Z | 时区的名字 | %Y | 完整的年份 |
>>> import time
>>> time.time()
- UTC:世界协调时
>>> time.ctime()
'Mon Jul 8 09:47:54 2019'
- 九元组struct_time
>>> time.localtime()
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=8, tm_hour=9, tm_min=49, tm_sec=5, tm_wday=0, tm_yday=189, tm_isdst=0)
>>> t = time.localtime()
>>> t.tm_year
2019
>>> t.tm_hour
9
time模块
>>> time.sleep(3) # 睡眠3秒
>>> time.strftime('%Y-%m-%d %H:%M:%S') # 转成指定格式
'2019-07-08 09:59:59'
# 字符串时间转成9元组格式
>>> time.strptime('2019-07-08 09:59:59', '%Y-%m-%d %H:%M:%S')
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=8, tm_hour=9, tm_min=59, tm_sec=59, tm_wday=0, tm_yday=189, tm_isdst=-1)
datetime模块
datetime.today()
:返回一个表示当前本地时间的datetime对象datetime.now([tz])
:返回一个表示当前本地时间的datetime对象,如果提供了参数tz,则获取tz参数所指时区的本地时间datetime.strptime(date_string, format)
:将格式字符串转换为datetime对象datetime.ctime(datetime对象)
:返回时间格式字符串datetime.strftime(format)
:返回指定格式字符串
>>> import datetime
>>> t1 = datetime.datetime.now()
>>> t1
datetime.datetime(2019, 7, 8, 10, 54, 25, 922956)
# 因为上面的写法太长了,可以改为以下方式
>>> from datetime import datetime
>>> t1 = datetime.now()
>>> t1 # 年月日时分秒毫秒
datetime.datetime(2019, 7, 8, 10, 55, 17, 81886)
>>> t1.year, t1.month, t1.day, t1.hour, t1.minute, t1.second, t1.microsecond
(2019, 7, 8, 10, 55, 17, 81886)
>>> t1.year
2019
# 将datetime对象转成时间字符串
>>> datetime.strftime(t1, '%Y-%m-%d %H:%M:%S')
'2019-07-08 10:55:17'
# 将时间字符串转换成datetime对象
>>> datetime.strptime('2019-07-08 10:55:17', '%Y-%m-%d %H:%M:%S')
datetime.datetime(2019, 7, 8, 10, 55, 17)
# 创建指定时间的datetime对象
>>> t = datetime(2019, 7, 8)
>>> t
datetime.datetime(2019, 7, 8, 0, 0)
计算时间差额,如100天零4小时前、100天零4小时后是什么时候
>>> from datetime import datetime, timedelta
>>> dt = timedelta(days=100, hours=4)
>>> t = datetime.now()
>>> t
datetime.datetime(2019, 7, 8, 11, 38, 13, 922027)
>>> t - dt
datetime.datetime(2019, 3, 30, 7, 38, 13, 922027)
>>> t + dt
datetime.datetime(2019, 10, 16, 15, 38, 13, 922027)
异常处理
什么是异常
- 当python检测到一个错误时,解释器就会指出当前流已经无法继续执行下去,这时候就出现了异常
- 异常是因为程序出现了错误而在正常控制流以外采取的行为
- 这个行为又分为两个阶段:
- 首先是引起异常发生的错误
- 然后是检测(和采取可能的措施)阶段
python中的异常
- 当程序运行时,因为遇到未解的错误而导致中止运行,便会出现traceback消息,打印异常
异常 | 描述 |
---|---|
NameError | 未声明/初始化对象 |
IndexError | 序列中没有没有此索引 |
SyntaxError | 语法错误 |
KeyboardInterrupt | 用户中断执行 |
EOFError | 没有内建输入,到达EOF标记 |
IOError | 输入/输出操作失败 |
try-except语句
- 定义了进行异常监控的一段代码,并且提供了处理异常的机制
异常处理就是把有可能发生异常的语句发到try中去执行,用except捕获发生的异常。完整的语法是:
try:
有可能发生异常的语句
except 异常名字:
处理异常的代码
else:
不发生异常才执行的代码
finally:
不管异常是否发生,都要执行的代码
触发异常
raise语句
- 要想引发异常,最简单的形式就是输入关键字raise,后面跟要引发的异常的名称
- 执行raise语句时,Python会创建指定的异常类的一个对象
- raise语句还可指定对异常对象进行初始化的参数
断言
- 断言是一句必须等价于布尔值为真的判定
- 此外,发生异常也意味着表达式为假
>>> assert 10 > 100, "Wrong"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Wrong
os模块
os模块简介
- 对文件系统的访问大多通过python的os模块实现
- 该模块是python访问操作系统功能的主要接口
- 有些方法,如copy等,并没有提供,可以使用shutil模块作为补充
os模块方法
函数 | 作用 |
---|---|
symlink() | 创建符号链接 |
listdir() | 列出指定目录的文件 |
getcwd() | 返回当前工作目录 |
mkdir() | 创建目录 |
chmod() | 改变权限模式 |
getatime() | 返回最近访问时间 |
chdir() | 改变工作目录 |
>>> import os
>>> os.getcwd() # pwd
>>> os.listdir() # ls
>>> os.listdir('/tmp') # ls /tmp
>>> os.makedirs('/tmp/mydemo/mydir') # mkdir -p
>>> os.mkdir('/tmp/abcde') # mkdir
>>> os.chdir('/tmp/mydemo/mydir') # cd /tmp/mydemo/mydir
>>> os.listdir()
[]
>>> os.mknod('hello') # touch hello
>>> os.listdir()
['hello']
>>> os.symlink('/etc/hosts', 'zhuji') # ln -s /etc/hosts zhuji
>>> os.chmod('hello', 0o644) # chmod 644 hello
>>> os.rename('hello', 'welcome') # mv hello welcome
>>> os.rmdir('/tmp/abcde') # rmdir /tmp/abcde 只能删空目录
>>> os.unlink('zhuji') # unlink zhuji # 删除软链接
>>> os.remove('welcome') # rm -f welcome
os.path子模块
>>> os.path.abspath('.') # 当前路径的绝对路径
'/tmp/mydemo/mydir'
>>> os.path.split('/tmp/demo/abc.txt') # 路径切割
('/tmp/demo', 'abc.txt')
>>> os.path.dirname('/tmp/demo/abc.txt')
'/tmp/demo'
>>> os.path.basename('/tmp/demo/abc.txt')
'abc.txt'
>>> os.path.join('/tmp/demo', 'abc.txt') # 路径拼接
'/tmp/demo/abc.txt'
>>> os.path.isdir('/etc') # 存在并且是目录吗?
True
>>> os.path.isfile('/etc/hosts') # 存在并且是文件吗?
True
>>> os.path.islink('/etc/passwd') # 存在并且是链接吗?
False
>>> os.path.ismount('/') # 存在并且是挂载点吗?
True
>>> os.path.exists('/abcd') # 存在吗?
False
pickle模块
pickle模块简介
- 把数据写入文件时,常规的文件方法只能把字符串对象写入。其他数据需先转换成字符串再写入文件 。
- python提供了一个标准的模块,称为pickle。使用它可以在一个文件中储存任何python对象,之后又可以把它完整无缺地取出来
当写入文件时,只能写入字符串,写入其他类型的数据,就会报错:
>>> f = open('/tmp/abc.txt', 'w')
>>> f.write('hello world!\n')
13
>>> f.write(100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: write() argument must be str, not int
pickle模块可以把任意的数据类型写到文件中,还能无损地取出。
>>> import pickle
>>> shopping_list = ['apple', 'banana', 'orage']
>>> with open('/tmp/shop.data', 'wb') as fobj:
... pickle.dump(shopping_list, fobj)
# 取出数据,还是列表的形式
>>> import pickle
>>> with open('/tmp/shop.data', 'rb') as fobj:
... mylist = pickle.load(fobj)
...
>>> type(mylist)
<class 'list'>
>>> mylist
['apple', 'banana', 'orage']
记账程序练习
记账程序
- 假设在记账时,有一万元钱
- 无论是开销还是收入都要进行记账
- 记账内容包括时间、金额和说明等
- 记账数据要求永久存储
日期 | 收入 | 支出 | 余额 | 说明 |
---|---|---|---|---|
2019-07-08 | 0 | 0 | 10000 | init |
2019-07-09 | 10000 | 0 | 20000 | salary |
2019-07-09 | 0 | 200 | 19800 | eat |
import os,pickle,time,json
# 日期,收入,支出,余额,说明
fileSrc = '/my/book.data'
#保存数据
def save_data(book_dict):
cur_balance = float(book_dict['income']) - float(book_dict['pay'])
if os.path.exists(fileSrc):
with open(fileSrc, 'rb') as fobj:
lists = pickle.load(fobj)
lists = list(lists)
if lists:
last_record = lists[-1]
balance = float(last_record['balance']) + cur_balance
book_dict['balance'] = '%.2f' % (balance)
lists.append(book_dict)
else:
book_dict['balance'] = '%.2f' % (cur_balance)
lists = [book_dict]
else:
book_dict['balance'] = '%.2f'%(cur_balance)
lists = [book_dict]
with open(fileSrc, 'wb') as fobj:
pickle.dump(lists, fobj)
#添加记录
def add_recode():
record_dict = {}
while True:
income = input('请输入您的收入金额(元):').strip()
try:
if type(eval(income)) == float or type(eval(income)) == int:
break
except:
print('输入不合法,请重新输入')
continue
while True:
pay = input('请输入您的支出金额(元):').strip()
try:
if type(eval(pay)) == float or type(eval(pay)) == int:
break
except:
print('输入不合法,请重新输入')
continue
info = input('请输入您的记录说明:').strip()
if not info:
info = ' '
balance = ''
record_time = time.strftime('%Y-%m-%d %H:%M:%S')
record_dict['record_time'] = record_time
record_dict['income'] = income
record_dict['pay'] = pay
record_dict['info'] = info
record_dict['balance'] = balance
save_data(record_dict)
#检索数据
def check_data(timeStr,tag='0'):
if os.path.exists(fileSrc):
lists = []
with open(fileSrc, 'rb') as fobj:
lists = list(pickle.load(fobj)).copy()
if tag == '0': #查看所有数据
return lists
if tag == '-1': #查看最新数据
return lists[-1]
if tag == '-3': #查看某天的数据
c_lists = []
for i in lists:
if timeStr in i['record_time']:
c_lists.append(i)
return c_lists
if tag == '-2': # 删除某天的数据
for i in lists[:]:
if timeStr in i['record_time']:
lists.remove(i)
with open(fileSrc, 'wb') as obj:
pickle.dump(lists, obj)
return lists
else:
print('暂无数据记录')
#查看所有数据
def check_all_data():
data = check_data('','0')
jsonobj = json.dumps(data,sort_keys=True,indent=4)
print(jsonobj)
#查看最新数据
def check_new_data():
data = check_data('','-1')
jsonobj = json.dumps(data,sort_keys=True,indent=4)
print(jsonobj)
#查看某天数据
def check_one_date():
while True:
try:
timeStr = input('请输入你要查看的日期,日期格式为(2019-07-08):').strip()
timeDate = time.strptime(timeStr,'%Y-%m-%d')
data = check_data(timeStr,'-3')
jsonobj = json.dumps(data, sort_keys=True, indent=4)
print(jsonobj)
break
except:
print('请输入正确的日期格式')
continue
#删除某天的数据
def delete_data_with_date():
while True:
try:
timeStr = input('请输入您想删除的数据日期,日期格式为(2019-07-08):').strip()
timeDate = time.strptime(timeStr,'%Y-%m-%d')
data = check_data(timeStr,'-2')
jsonobj = json.dumps(data, sort_keys=True, indent=4)
print(jsonobj)
break
except:
print('请输入正确的日期格式')
continue
def start_recode():
while True:
prompt = input('''0-添加记录
1-获取所有记录
2-查看最近的一条记录
3-查看某天的记录
4-删除某天的记录
5-退出
请输入您要操作的选项:''').strip()
cmds = {'0':add_recode,'1':check_all_data,'2':check_new_data,'3':check_one_date,'4':delete_data_with_date}
if prompt not in ['0','1','2','3','4','5']:
print('输入不合法,请重新输入')
continue
if prompt == '5':
print('Bye-bye')
break
cmds[prompt]()
if __name__ == '__main__':
start_recode()