1. 程式人生 > >【29】Python淺入六個常用模塊

【29】Python淺入六個常用模塊

python sys pickle time() 模塊

1.使用copy模塊
copy模塊包含了制作對象的拷貝的函數。當寫程序時,有時候你可能需要多個相同的對象。這時候就可以用copy模塊進行拷貝。
例如:
我們創建一個Ad類,它有一個init函數,參數為name(名字),school_record(學習成績),color(顏色)

class Ad:
     def __init__(self,name,school_record,color):
            self.name=name
            self.school_record=school_record
            self.color=color

下面我們可以創建一個Ad類的新對象。

Harry=Ad("alex",80,"red")
假設我們想要多復制幾條就可以使用copy模塊

>>>import copy
>>>Harry=Ad("alex",80,"red")
>>>Harriet=copy.copy(Harry)
>>>print(Harry.name)
>>>print(Harriet.name)
alex
alex

在這個例子中我們創建對象並把它標記為Harry,然後我們創建了這個對象的一個拷貝,並標記為Harriet。盡管他們都是同一個人的成績,但它們是兩個完全不同的對象。在這裏它的作用只是少寫幾行代碼,但當對象更加復雜時,拷貝就更有用武之地。

>>>Harry=Ad("alex",80,"red")
>>>Carriet=Ad("Ying",99,"while")
>>>Jack=Ad("Li",30,"black")
>>>my_animals=[Harry,Carriet,Jack]
>>>more_animals=copy.copy(my_animals)
>>>print(more_animals[0].name)
>>>print(more_animals[1].name)

在前三行,我們創建了三個對象Harry,Carriet和Jack。在第四行我們將對象添加到my_animals列表中。我們用copy復制了這個列表。最後打印結果

alex
Ying

如果我們改變了某個學員的成績,來看看將會發生什麽?

>>>my_animals[0].name=10
>>>print(my_animals[0].name)
>>>print(more_animals[0].name)
10
10

太奇怪了,我們改的不是my_animals中的成績嘛,為什麽兩個列表的值都變了?
成績都變了,是因為copy實際上只做了淺拷貝,也就是說它不會拷貝我們要拷貝的對象中的對象。在這裏,它拷貝的是list對象,但並沒有copy其中的每個對象。因此我們得到的是一個新列表,但其中的對象並不是新的,列表more_animals中還是那三個同樣的對象。
同樣用這些變量,如果我們給第一個列表(my_animals)添加一個新的Ad的話,它不會出現拷貝(more_animals)中。下面可以進行驗證

>>>salay=[‘Tom‘,55,‘pick‘]
>>>my_animals.append(salay)
>>>print(len(my_animals))
>>>print(len(more_animals))
4
3

結果如你所見!
在copy模塊中的另一函數deepcopy,則會創建被拷貝對象中的所有對象的拷貝。當我們用deepcopy來復制my_animals時,我們會得到一個新列表,它的內容是對所有對象的拷貝。這樣的結果是,對於原來列表中Ad對象的改動不會影響到新列表。看下面例子:

>>>more_animals=copy.deepcopy(my_animals)
>>>my_animals[0].name="ALEX"
>>>print(my_animals[0].name)
>>>print(more_animals[0].name)
ALEX
alex

總結:copy模塊中兩種函數淺拷貝copy與深拷貝deepcopy的區別。
當copy一個列表時。淺拷貝不會對列表裏面的對象進行拷貝,所以當被拷貝列表裏面新增對象的話,淺拷貝不會新增對象。而如果對被拷貝列表進行修改時,淺拷貝會跟著變動。而深拷貝會對列表裏面的對象進行拷貝相當於獨立一個列表,所以當被拷貝列表新增對象時,深拷貝也會新增對象,而如果對被拷貝列表進行修改時,深拷貝不會變化。

2.使用keyword模塊
keyword模塊記錄的python自身的一些關鍵詞,這些關鍵詞是不可以被拿來做變量名使用的。可以使用如下方式查看包含哪些關鍵詞。

>>>import keyword
>>>print(keyword.kwlist)
[‘False‘, ‘None‘, ‘True‘, ‘and‘, ‘as‘, ‘assert‘, ‘break‘, ‘class‘, ‘continue‘, ‘def‘, ‘del‘, ‘elif‘, ‘else‘, ‘except‘, ‘finally‘, ‘for‘, ‘from‘, ‘global‘, ‘if‘, ‘import‘, ‘in‘, ‘is‘, ‘lambda‘, ‘nonlocal‘, ‘not‘, ‘or‘, ‘pass‘, ‘raise‘, ‘return‘, ‘try‘, ‘while‘, ‘with‘, ‘yield‘]

3.使用random模塊
可以通過random模塊獲取隨機數。random模塊中最有用的幾個函數是randint,choice還有shuffle。
3.1 randint函數用於隨機挑選一個數字

import random
num=random.randint(1,10)
print(num)

這裏可以寫個猜數字遊戲。

import random
into=int(random.randint(1,100))
while True:
    num=int(input("Please input number: "))
    if num==into:
        print("恭喜你")
        break
    elif num > into:
        print("big")
    else:
        print("small")

運行結果:

Please input number: 50
small
Please input number: 70
big
Please input number: 60
small
Please input number: 69
恭喜你

3.2 choice函數用於從列表中隨機挑選一個

>>>import random
>>>lists=[‘red‘,‘pick‘,‘while‘,‘black‘,‘yellow‘]
>>>t=random.choice(lists)
>>>print(t)
black

3.3 shuffle函數對列表重新"洗牌",適用於類似撲克牌類的遊戲。

>>>import random
>>>lists_shuffle=[‘red‘,‘pick‘,‘while‘,‘black‘,‘yellow‘]
>>>random.shuffle(lists_shuffle)
>>>print(lists_shuffle)
[‘red‘, ‘yellow‘, ‘while‘, ‘black‘, ‘pick‘]

4.使用sys模塊
在sys模塊中有一些系統函數,用來控制python shell程序自身。
我們來看下如何使用exit函數,stdin和stdout對象,還有version變量。

4.1用exit函數來退出shell程序

import sys
sys.exit()

4.2從stdin對象讀取
sys模塊中的stdin對象(standard input標準輸入)會提示用戶輸入信息,讀取到shell程序中並在程序中使用。這個對象有個readline函數,它能讀取從鍵盤輸入的一行文本,直到用戶按了回車。

>>>import sys
>>>v=sys.stdin.readline()
this is Python sys.
>>>print(v)
this is Python sys.

遺留問題:readline和input函數區別?

4.3從stdout對象來寫入
與stdin對象不同,stdout對象(standard output標準輸出)可以用來向shell程序寫消息,而不是從中讀入。在某些方面它與print相同,但是stout是一個文件對象。

>>>import sys
>>>sys.stdout.write("this is sys")
this is sys

4.4我們來看下當前python版本

>>>import sys
>>>print(sys.version)
3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]

5.使用time模塊
python中的time模塊包含了表示時間的函數,不過可能與你期望不太一樣。

>>>import time
>>>print(time.time())
1521968583.4384

對於time()的調用所返回的數字實際上是從1970年1月1日00:00:00AM以來的秒數。單獨看起來這種罕見的表示形式沒法直接使用它,但它有它的目的。你可以用來記錄一段程序執行的多長時間。

import time
def lost_of(max):
    start_time=time.time()
    for i in range(max):
        print(i)
    stop_time=time.time()
    print("花費時間:%s" %(stop_time-start_time))

lost_of(999)

5.1用asctime轉換日期
asctime函數是以日期的元組為參數,並把它轉換成更可讀的形式。不用任何參數調用,asctime就會以可讀的形式返回當前的日期和時間。

>>>import time
>>>print(time.asctime())
Sun Mar 25 17:10:46 2018

5.2用localtime來得到日期和時間

>>>import time
>>>print(time.localtime())
time.struct_time(tm_year=2018, tm_mon=3, tm_mday=25, tm_hour=17, tm_min=11, tm_sec=36, tm_wday=6, tm_yday=84, tm_isdst=0)

tm_year:年份
tm_mon:月份
tm_mday:日期
tm_hour:小時
tm_min:分鐘
tm_sec:秒
tm_wday:禮拜幾(0等於禮拜一)
tm_yday:從1月1至今的天數
tm_isdst:夏令時(0不是夏令時)

5.3用sleep來休息一會兒

import time
for x in range(1,20):
    print(x)
    time.sleep(1)  ###這裏sleep(1),表示休息1s

6.使用pickle模塊
pickle模塊可以用來保存信息,原意為"腌菜"。pickle模塊用來把python對象轉換成可以方便寫入的文件和從文件讀取的形式。
如果你在寫一個遊戲並且想保存玩家的進度信息的胡啊,可能會用得上pickle。
例如:給下列遊戲信息增加一個保存功能。
我們可以把這個字典保存到文件裏,只要已寫入的方式打開文件,然後調用pickle裏面的dump函數,像這樣:

import pickle

game_dict={
    "name":"Dy",
    "ID":1203,
    "player":"Tank",
    "money":9999
}
t=open("save_game","wb")  ###以二進制寫入方式打開文件
pickle.dump(game_dict,t) ###用dump,將game_dict信息寫入文件saver_game中。這一過程叫序列化
t.close() ##關閉文件

打開game_dict文件後,你會發現它是不像一個文本文件,而是一個亂七八糟的混合體。這種文件可以用反序列化來重新讀出數據。
技術分享圖片

被pickle過的python對象又叫序列化,至於為什麽叫序列化這個名字,這個外國人起的我也不清楚,反正大家都是這麽叫的。不過既然有序列化過程,當然就有反序列化,不然保存的文件又如何讀取出來呢。反序列化就要用load函數。方法很簡單,只要將保存的文件以可讀的方式打開,用load反序列化即可。方法如下:

local_file=open("save_game","rb")
t_load=pickle.load(local_file) ###將打開文件,進行反序列化,變成可讀文件
local_file.close()
print(t_load)

【29】Python淺入六個常用模塊