文章目录
时间方法
time模块
时间表示方法:
- 时间戳:自1970-1-1 0:00:00到某一时间点之间的秒数
- UTC时间:世界协调时。以英国格林威治这个城市所在的经度为基准,向东向西每15度角>划分一个时区,全球共24个时区。
- struct_time:九元组时间。年、月、日、时、分、秒、一周中的第几天、一年中的第几>天、是否使用夏季节约时间
- struct_time元组:
time模块的方法
- 时间样式:
https://docs.python.org/zh-cn/3/library/time.html
>>> import time
>>> time.time() # 返回时间戳
1581730776.0589788
>>> time.ctime() # 返回当前的时间字符串
'Sat Feb 15 09:40:52 2020'
>>> time.ctime(0) # 时间戳为0秒时的时间字符串
'Thu Jan 1 08:00:00 1970'
>>> time.localtime() # 反回当前时间的struct_time 9元组
time.struct_time(tm_year=2020, tm_mon=2, tm_mday=15, tm_hour=9, tm_min=41, tm_sec=55, tm_wday=5, tm_yday=46, tm_isdst=0)
>>> t = time.localtime()
>>> t.tm_year
2020
>>> t.tm_yday
46
>>> t.tm_wday
5
>>> time.sleep(3) # 睡眠3秒
>>> time.strftime('%Y-%m-%d %a %H:%M:%S') # 返回指定格式的字符串
'2020-02-15 Sat 10:18:32'
# 将时间字符串转为9元组时间格式后,可以比较时间大小
>>> time.strptime('2020-2-14 12:00:00', '%Y-%m-%d %H:%M:%S')
time.struct_time(tm_year=2020, tm_mon=2, tm_mday=14, tm_hour=12, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=45, tm_isdst=-1)
>>> t1 = time.strptime('2020-2-14 12:00:00', '%Y-%m-%d %H:%M:%S')
>>> t2 = time.strptime('2020-1-14 12:00:00', '%Y-%m-%d %H:%M:%S')
>>> t1 > t2
True
datetime模块
- 时间计算
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2020, 2, 15, 10, 54, 16, 416819)
# 以上写法有些冗长,可以使用下面的方式替代
>>> from datetime import datetime
>>> t = datetime.now() # 返回当前时间的年月日时分秒
>>> t.year, t.month, t.day, t.hour, t.minute, t.second
(2020, 2, 15, 10, 55, 41)
>>> t.strftime('%Y-%m-%d %H:%M:%S') # 转成字符串形式
'2020-02-15 10:55:41'
# 将时间字符串,转换成datetime对象
>>> t = datetime.strptime('2020-02-15 10:55:41', '%Y-%m-%d %H:%M:%S')
>>> t
datetime.datetime(2020, 2, 15, 10, 55, 41)
# 得到100天1小时之前的时间,100天1小时之后的时间
>>> from datetime import datetime, timedelta
>>> days = timedelta(days=100, hours=1)
>>> t = datetime.now()
>>> t + days
datetime.datetime(2020, 5, 25, 12, 24, 15, 407633)
>>> t - days
datetime.datetime(2019, 11, 7, 10, 24, 15, 407633)
异常处理
- 异常就是不正常,当程序遇到各种各样错误时,程序将会崩溃,终止执行。
- 异常处理就是提前想到程序可能出现的错误,并给出解决方案。使得程序可以继续进行下
去,不要再崩溃 - 异常处理语法格式:
try:
有可能发生异常的代码
except 异常1:
发生异常1时要执行的代码
except 异常2:
发生异常2时要执行的代码
... ...
except 异常n:
发生异常n时要执行的代码
else:
不发生异常才执行的代码
finally:
不管异常是否发生,一定会执行的语速句
触发异常
- 通过raise关键字,抛出异常
- 通过assert关键字,抛出AssertionError,即断言异常
创建mydiv.py脚本,要求如下:
– 提示用户输入一个数字作为除数
– 如果用户按下Ctrl+C或Ctrl+D则退出程序
– 如果用户输入非数字字符,提示用户应该输入数字
– 如果用户输入0,提示用户0不能作为除数
#!/usr/bin/env python3
try:
num = int(input("number: "))
result = 100 / num
except ValueError:
print('请输入数字')
except ZeroDivisionError:
print('不允许使用0')
except (KeyboardInterrupt, EOFError):
print('\nBye-bye')
else:
print(result) # 不发生异常才执行的语句
finally:
print('Done') # 不管异常是否发生都要执行的语句
print('end of program')
#不是必须把所有的语句写全,常用的有try-except和try-finally组合
创建myerror.py脚本,要求如下:
– 编写第一个函数,函数接收姓名和年龄,如果年龄不在1到120之间,产生ValueError异常
– 编写第二个函数,函数接收姓名和年龄,如果年龄不在1到120之间,产生断言异常
#!/usr/bin/env python3
def set_age(name, age):
if not 0 < age < 120:
raise ValueError("age out of range.")
print("%s is %s years old" % (name, age))
def set_age2(name, age):
assert 0 < age < 120, 'age out of range.'
print("%s is %s years old" % (name, age))
if __name__ == '__main__':
set_age('bob', 25)
set_age2('bob', 121)
os模块
- os模块是python访问文件系统主要采用的模块
>>> import os
>>> os.getcwd() # pwd
'/var/ftp/nsd2019/nsd1909/py02/day01'
>>> os.listdir() # ls
>>> os.listdir('/tmp') # ls /tmp
>>> os.mkdir('/tmp/nsd1909') # mkdir /tmp/nsd1909
>>> os.makedirs('/tmp/aaa/bbb/cccc') # mkdir -p /tmp/aaa/bbb/cccc
>>> os.chdir('/tmp/nsd1909') # cd /tmp/nsd1909
>>> os.getcwd()
'/tmp/nsd1909'
>>> os.mknod('hi.txt') # touch hi.txt
>>> os.listdir()
['hi.txt']
>>> os.symlink('/etc/hosts', 'zhuji') # ln -s /etc/hosts zhuji
>>> os.remove('hi.txt') # rm -f hi.txt
>>> os.listdir()
['zhuji']
>>> os.mknod('hello.txt')
[root@localhost day01]# ll /tmp/nsd1909/hello.txt
-rw------- 1 root root 0 2月 15 13:45 /tmp/nsd1909/hello.txt
>>> os.chmod('hello.txt', 755)
[root@localhost day01]# ll /tmp/nsd1909/hello.txt
--wxrw--wt 1 root root 0 2月 15 13:45 /tmp/nsd1909/hello.txt
>>> os.chmod('hello.txt', 0o755) # 注意,linux权限是8进制数
[root@localhost day01]# ll /tmp/nsd1909/hello.txt
-rwxr-xr-x 1 root root 0 2月 15 13:45 /tmp/nsd1909/hello.txt
实现ls -R(os.walk)
>>> mulu = list(os.walk('/tmp/nsd1909'))
>>> mulu
[('/tmp/nsd1909', ['aaa', 'abc'], ['zhuji', 'hello.txt']), ('/tmp/nsd1909/aaa', ['bbb', 'ccc'], ['a.txt', 'b.txt']), ('/tmp/nsd1909/aaa/bbb', [], ['b1.txt', 'b2.txt']), ('/tmp/nsd1909/aaa/ccc', [], ['c1.txt', 'c2.txt']), ('/tmp/nsd1909/abc', [], ['hosts', 'passwd'])]
>>> len(mulu)
5
>>> mulu[0]
('/tmp/nsd1909', ['aaa', 'abc'], ['zhuji', 'hello.txt'])
>>> mulu[1]
('/tmp/nsd1909/aaa', ['bbb', 'ccc'], ['a.txt', 'b.txt'])
>>> mulu[2]
('/tmp/nsd1909/aaa/bbb', [], ['b1.txt', 'b2.txt'])
>>> mulu[3]
('/tmp/nsd1909/aaa/ccc', [], ['c1.txt', 'c2.txt'])
>>> mulu[4]
('/tmp/nsd1909/abc', [], ['hosts', 'passwd'])
# 经分析,lumu列表由5个元组构成。每个元组拥有一样的结构。
# 每个元组有三项内容: (字符串,列表1,列表2)
# 字符串:目录路径
# 列表1:目录路径下的子目录
# 列表2:目录路径下的文件
import os
path = '/tmp/nsd1909'
# for data in os.walk(path):
# print(data)
# for data in os.walk(path):
# print('%s:' % data[0])
# print(data[1])
# print(data[2])
# for data in os.walk(path):
# print('%s:' % data[0])
# for zimulu in data[1]:
# print('\033[34;1m%s\033[0m' % zimulu, end=' ')
# for file in data[2]:
# print(file, end=' ')
# print('\n')
# 元组有3项,可以将这3项分别赋值给3个变量
for path, folders, files in os.walk(path):
print('%s:' % path)
for zimulu in folders:
print('\033[34;1m%s\033[0m' % zimulu, end='\t')
for file in files:
print(file, end='\t')
print('\n')
os.path
>>> os.path.basename('/tmp/nsd2019/abc.txt')
'abc.txt'
>>> os.path.dirname('/tmp/nsd2019/abc.txt')
'/tmp/nsd2019'
>>> os.path.split('/tmp/nsd2019/abc.txt') # 切割路径
('/tmp/nsd2019', 'abc.txt')
>>> os.path.join('/tmp/nsd2019', 'abc.txt') # 路径拼接
'/tmp/nsd2019/abc.txt'
>>> os.path.isfile('/etc/hosts') # 文件存在并且是文件吗?
True
>>> os.path.isdir('/etc/hosts') # 存在并且是目录吗?
False
>>> os.path.islink('/etc/grub2.cfg') # 存在并且是链接文件吗?
True
>>> os.path.ismount('/') # 存在并且是挂载点吗?
True
>>> os.path.exists('/etc') # 存在吗?
True
pickle模块
- 文件默认只能写入str或bytes类型的数据
- pickle可以将任意类型的数据写入文件,还可以无损地取出来。
>>> import pickle
>>> gouwu = ['方便面', '速冻水饺', '苹果']
>>> with open('/tmp/shop.data', 'wb') as fobj:
... pickle.dump(gouwu, fobj) # 将列表存入文件
>>> with open('/tmp/shop.data', 'rb') as fobj:
... l = pickle.load(fobj) # 从文件中取出数据
...
>>> l
['方便面', '速冻水饺', '苹果']
>>> type(l)
<class 'list'>
记账脚本
假设在记账时,有一万元钱
无论是开销还是收入都要进行记账
记账内容包括时间、金额和说明等
记账数据要求永久存储
#!/usr/bin/env python3
# 日期 开销 收入 余额 备注
import os
import pickle
from time import strftime
def save(fname):
'用于记录收入'
date = strftime('%Y-%m-%d')
jin_e = int(input('金额: '))
shuoming = input('备注: ')
# 取出所有的记账内容
with open(fname, 'rb') as fobj:
data = pickle.load(fobj)
yu_e = data[-1][-2] + jin_e
# 构建最新一笔收入
line = [date, jin_e, 0, yu_e, shuoming]
data.append(line)
# 将记账内容写回文件
with open(fname, 'wb') as fobj:
pickle.dump(data, fobj)
def cost(fname):
'用于记录支出'
date = strftime('%Y-%m-%d')
jin_e = int(input('金额: '))
shuoming = input('备注: ')
# 取出所有的记账内容
with open(fname, 'rb') as fobj:
data = pickle.load(fobj)
yu_e = data[-1][-2] - jin_e
# 构建最新一笔支出
line = [date, 0, jin_e, yu_e, shuoming]
data.append(line)
# 将记账内容写回文件
with open(fname, 'wb') as fobj:
pickle.dump(data, fobj)
def query(fname):
'用于查帐'
# 取出数据
with open(fname, 'rb') as fobj:
data = pickle.load(fobj)
# 打印表头
print('%-12s%-8s%-8s%-12s%-20s' % ('date', 'save', 'cost', 'balance', 'comment'))
for line in data:
print('%-12s%-8s%-8s%-12s%-20s' % tuple(line))
# print('%-12s%-8s%-8s%-12s%-20s' %(line[0],line[1],line[2],line[3],line[4]))
def show_menu():
'用于展示主菜单'
cmds = {'0': save, '1': cost, '2': query}
prompt = '''(0) 收入
(1) 开销
(2) 查询
(3) 退出
请选择(0/1/2/3): '''
fname = 'account.data'
# 判断记账文件是否存在,如果不存在,初始化它
chushi = [[strftime('%Y-%m-%d'), 0, 0, 10000, 'init data']]
if not os.path.exists(fname):
with open(fname, 'wb') as fobj:
pickle.dump(chushi, fobj)
while 1:
xuan = input(prompt).strip()
if xuan not in ['0', '1', '2', '3']:
print('无效的输入,请重试。')
continue
if xuan == '3':
print('\nBye-bye')
break
cmds[xuan](fname)
if __name__ == '__main__':
show_menu()