文章目錄
時間方法
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()