python3:時間方法,異常處理,系統文件相關模塊(os)

時間方法

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 215 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 215 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 215 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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章